PHP and Javascript implementations of a simple markdown parser
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

phpunit.phar 4.9MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546875478754887549875508755187552875538755487555875568755787558875598756087561875628756387564875658756687567875688756987570875718757287573875748757587576875778757887579875808758187582875838758487585875868758787588875898759087591875928759387594875958759687597875988759987600876018760287603876048760587606876078760887609876108761187612876138761487615876168761787618876198762087621876228762387624876258762687627876288762987630876318763287633876348763587636876378763887639876408764187642876438764487645876468764787648876498765087651876528765387654876558765687657876588765987660876618766287663876648766587666876678766887669876708767187672876738767487675876768767787678876798768087681876828768387684876858768687687876888768987690876918769287693876948769587696876978769887699877008770187702877038770487705877068770787708877098771087711877128771387714877158771687717877188771987720877218772287723877248772587726877278772887729877308773187732877338773487735877368773787738877398774087741877428774387744877458774687747877488774987750877518775287753877548775587756877578775887759877608776187762877638776487765877668776787768877698777087771877728777387774877758777687777877788777987780877818778287783877848778587786877878778887789877908779187792877938779487795877968779787798877998780087801878028780387804878058780687807878088780987810878118781287813878148781587816878178781887819878208782187822878238782487825878268782787828878298783087831878328783387834878358783687837878388783987840878418784287843878448784587846878478784887849878508785187852878538785487855878568785787858878598786087861878628786387864878658786687867878688786987870878718787287873878748787587876878778787887879878808788187882878838788487885878868788787888878898789087891878928789387894878958789687897878988789987900879018790287903879048790587906879078790887909879108791187912879138791487915879168791787918879198792087921879228792387924879258792687927879288792987930879318793287933879348793587936879378793887939879408794187942879438794487945879468794787948879498795087951879528795387954879558795687957879588795987960879618796287963879648796587966879678796887969879708797187972879738797487975879768797787978879798798087981879828798387984879858798687987879888798987990879918799287993879948799587996879978799887999880008800188002880038800488005880068800788008880098801088011880128801388014880158801688017880188801988020880218802288023880248802588026880278802888029880308803188032880338803488035880368803788038880398804088041880428804388044880458804688047880488804988050880518805288053880548805588056880578805888059880608806188062880638806488065880668806788068880698807088071880728807388074880758807688077880788807988080880818808288083880848808588086880878808888089880908809188092880938809488095880968809788098880998810088101881028810388104881058810688107881088810988110881118811288113881148811588116881178811888119881208812188122881238812488125881268812788128881298813088131881328813388134881358813688137881388813988140881418814288143881448814588146881478814888149881508815188152881538815488155881568815788158881598816088161881628816388164881658816688167881688816988170881718817288173881748817588176881778817888179881808818188182881838818488185881868818788188881898819088191881928819388194881958819688197881988819988200882018820288203882048820588206882078820888209882108821188212882138821488215882168821788218882198822088221882228822388224882258822688227882288822988230882318823288233882348823588236882378823888239882408824188242882438824488245882468824788248882498825088251882528825388254882558825688257882588825988260882618826288263882648826588266882678826888269882708827188272882738827488275882768827788278882798828088281882828828388284882858828688287882888828988290882918829288293882948829588296882978829888299883008830188302883038830488305883068830788308883098831088311883128831388314883158831688317883188831988320883218832288323883248832588326883278832888329883308833188332883338833488335883368833788338883398834088341883428834388344883458834688347883488834988350883518835288353883548835588356883578835888359883608836188362883638836488365883668836788368883698837088371883728837388374883758837688377883788837988380883818838288383883848838588386883878838888389883908839188392883938839488395883968839788398883998840088401884028840388404884058840688407884088840988410884118841288413884148841588416884178841888419884208842188422884238842488425884268842788428884298843088431884328843388434884358843688437884388843988440884418844288443884448844588446884478844888449884508845188452884538845488455884568845788458884598846088461884628846388464884658846688467884688846988470884718847288473884748847588476884778847888479884808848188482884838848488485884868848788488884898849088491884928849388494884958849688497884988849988500885018850288503885048850588506885078850888509885108851188512885138851488515885168851788518885198852088521885228852388524885258852688527885288852988530885318853288533885348853588536885378853888539885408854188542885438854488545885468854788548885498855088551885528855388554885558855688557885588855988560885618856288563885648856588566885678856888569885708857188572885738857488575885768857788578885798858088581885828858388584885858858688587885888858988590885918859288593885948859588596885978859888599886008860188602886038860488605886068860788608886098861088611886128861388614886158861688617886188861988620886218862288623886248862588626886278862888629886308863188632886338863488635886368863788638886398864088641886428864388644886458864688647886488864988650886518865288653886548865588656886578865888659886608866188662886638866488665886668866788668886698867088671886728867388674886758867688677886788867988680886818868288683886848868588686886878868888689886908869188692886938869488695886968869788698886998870088701887028870388704887058870688707887088870988710887118871288713887148871588716887178871888719887208872188722887238872488725887268872788728887298873088731887328873388734887358873688737887388873988740887418874288743887448874588746887478874888749887508875188752887538875488755887568875788758887598876088761887628876388764887658876688767887688876988770887718877288773887748877588776887778877888779887808878188782887838878488785887868878788788887898879088791887928879388794887958879688797887988879988800888018880288803888048880588806888078880888809888108881188812888138881488815888168881788818888198882088821888228882388824888258882688827888288882988830888318883288833888348883588836888378883888839888408884188842888438884488845888468884788848888498885088851888528885388854888558885688857888588885988860888618886288863888648886588866888678886888869888708887188872888738887488875888768887788878888798888088881888828888388884888858888688887888888888988890888918889288893888948889588896888978889888899889008890188902889038890488905889068890788908889098891088911889128891388914889158891688917889188891988920889218892288923889248892588926889278892888929889308893188932889338893488935889368893788938889398894088941889428894388944889458894688947889488894988950889518895288953889548895588956889578895888959889608896188962889638896488965889668896788968889698897088971889728897388974889758897688977889788897988980889818898288983889848898588986889878898888989889908899188992889938899488995889968899788998889998900089001890028900389004890058900689007890088900989010890118901289013890148901589016890178901889019890208902189022890238902489025890268902789028890298903089031890328903389034890358903689037890388903989040890418904289043890448904589046890478904889049890508905189052890538905489055890568905789058890598906089061890628906389064890658906689067890688906989070890718907289073890748907589076890778907889079890808908189082890838908489085890868908789088890898909089091890928909389094890958909689097890988909989100891018910289103891048910589106891078910889109891108911189112891138911489115891168911789118891198912089121891228912389124891258912689127891288912989130891318913289133891348913589136891378913889139891408914189142891438914489145891468914789148891498915089151891528915389154891558915689157891588915989160891618916289163891648916589166891678916889169891708917189172891738917489175891768917789178891798918089181891828918389184891858918689187891888918989190891918919289193891948919589196891978919889199892008920189202892038920489205892068920789208892098921089211892128921389214892158921689217892188921989220892218922289223892248922589226892278922889229892308923189232892338923489235892368923789238892398924089241892428924389244892458924689247892488924989250892518925289253892548925589256892578925889259892608926189262892638926489265892668926789268892698927089271892728927389274892758927689277892788927989280892818928289283892848928589286892878928889289892908929189292892938929489295892968929789298892998930089301893028930389304893058930689307893088930989310893118931289313893148931589316893178931889319893208932189322893238932489325893268932789328893298933089331893328933389334893358933689337893388933989340893418934289343893448934589346893478934889349893508935189352893538935489355893568935789358893598936089361893628936389364893658936689367893688936989370893718937289373893748937589376893778937889379893808938189382893838938489385893868938789388893898939089391893928939389394893958939689397893988939989400894018940289403894048940589406894078940889409894108941189412894138941489415894168941789418894198942089421894228942389424894258942689427894288942989430894318943289433894348943589436894378943889439894408944189442894438944489445894468944789448894498945089451894528945389454894558945689457894588945989460894618946289463894648946589466894678946889469894708947189472894738947489475894768947789478894798948089481894828948389484894858948689487894888948989490894918949289493894948949589496894978949889499895008950189502895038950489505895068950789508895098951089511895128951389514895158951689517895188951989520895218952289523895248952589526895278952889529895308953189532895338953489535895368953789538895398954089541895428954389544895458954689547895488954989550895518955289553895548955589556895578955889559895608956189562895638956489565895668956789568895698957089571895728957389574895758957689577895788957989580895818958289583895848958589586895878958889589895908959189592895938959489595895968959789598895998960089601896028960389604896058960689607896088960989610896118961289613896148961589616896178961889619896208962189622896238962489625896268962789628896298963089631896328963389634896358963689637896388963989640896418964289643896448964589646896478964889649896508965189652896538965489655896568965789658896598966089661896628966389664896658966689667896688966989670896718967289673896748967589676896778967889679896808968189682896838968489685896868968789688896898969089691896928969389694896958969689697896988969989700897018970289703897048970589706897078970889709897108971189712897138971489715897168971789718897198972089721897228972389724897258972689727897288972989730897318973289733897348973589736897378973889739897408974189742897438974489745897468974789748897498975089751897528975389754897558975689757897588975989760897618976289763897648976589766897678976889769897708977189772897738977489775897768977789778897798978089781897828978389784897858978689787897888978989790897918979289793897948979589796897978979889799898008980189802898038980489805898068980789808898098981089811898128981389814898158981689817898188981989820898218982289823898248982589826898278982889829898308983189832898338983489835898368983789838898398984089841898428984389844898458984689847898488984989850898518985289853898548985589856898578985889859898608986189862898638986489865898668986789868898698987089871898728987389874898758987689877898788987989880898818988289883898848988589886898878988889889898908989189892898938989489895898968989789898898998990089901899028990389904899058990689907899088990989910899118991289913899148991589916899178991889919899208992189922899238992489925899268992789928899298993089931899328993389934899358993689937899388993989940899418994289943899448994589946899478994889949899508995189952899538995489955899568995789958899598996089961899628996389964899658996689967899688996989970899718997289973899748997589976899778997889979899808998189982899838998489985899868998789988899898999089991899928999389994899958999689997899988999990000900019000290003900049000590006900079000890009900109001190012900139001490015900169001790018900199002090021900229002390024900259002690027900289002990030900319003290033900349003590036900379003890039900409004190042900439004490045900469004790048900499005090051900529005390054900559005690057900589005990060900619006290063900649006590066900679006890069900709007190072900739007490075900769007790078900799008090081900829008390084900859008690087900889008990090900919009290093900949009590096900979009890099901009010190102901039010490105901069010790108901099011090111901129011390114901159011690117901189011990120901219012290123901249012590126901279012890129901309013190132901339013490135901369013790138901399014090141901429014390144901459014690147901489014990150901519015290153901549015590156901579015890159901609016190162901639016490165901669016790168901699017090171901729017390174901759017690177901789017990180901819018290183901849018590186901879018890189901909019190192901939019490195901969019790198901999020090201902029020390204902059020690207902089020990210902119021290213902149021590216902179021890219902209022190222902239022490225902269022790228902299023090231902329023390234902359023690237902389023990240902419024290243902449024590246902479024890249902509025190252902539025490255902569025790258902599026090261902629026390264902659026690267902689026990270902719027290273902749027590276902779027890279902809028190282902839028490285902869028790288902899029090291902929029390294902959029690297902989029990300903019030290303903049030590306903079030890309903109031190312903139031490315903169031790318903199032090321903229032390324903259032690327903289032990330903319033290333903349033590336903379033890339903409034190342903439034490345903469034790348903499035090351903529035390354903559035690357903589035990360903619036290363903649036590366903679036890369903709037190372903739037490375903769037790378903799038090381903829038390384903859038690387903889038990390903919039290393903949039590396903979039890399904009040190402904039040490405904069040790408904099041090411904129041390414904159041690417904189041990420904219042290423904249042590426904279042890429904309043190432904339043490435904369043790438904399044090441904429044390444904459044690447904489044990450904519045290453904549045590456904579045890459904609046190462904639046490465904669046790468904699047090471904729047390474904759047690477904789047990480904819048290483904849048590486904879048890489904909049190492904939049490495904969049790498904999050090501905029050390504905059050690507905089050990510905119051290513905149051590516905179051890519905209052190522905239052490525905269052790528905299053090531905329053390534905359053690537905389053990540905419054290543905449054590546905479054890549905509055190552905539055490555905569055790558905599056090561905629056390564905659056690567905689056990570905719057290573905749057590576905779057890579905809058190582905839058490585905869058790588905899059090591905929059390594905959059690597905989059990600906019060290603906049060590606906079060890609906109061190612906139061490615906169061790618906199062090621906229062390624906259062690627906289062990630906319063290633906349063590636906379063890639906409064190642906439064490645906469064790648906499065090651906529065390654906559065690657906589065990660906619066290663906649066590666906679066890669906709067190672906739067490675906769067790678906799068090681906829068390684906859068690687906889068990690906919069290693906949069590696906979069890699907009070190702907039070490705907069070790708907099071090711907129071390714907159071690717907189071990720907219072290723907249072590726907279072890729907309073190732907339073490735907369073790738907399074090741907429074390744907459074690747907489074990750907519075290753907549075590756907579075890759907609076190762907639076490765907669076790768907699077090771907729077390774907759077690777907789077990780907819078290783907849078590786907879078890789907909079190792907939079490795907969079790798907999080090801908029080390804908059080690807908089080990810908119081290813908149081590816908179081890819908209082190822908239082490825908269082790828908299083090831908329083390834908359083690837908389083990840908419084290843908449084590846908479084890849908509085190852908539085490855908569085790858908599086090861908629086390864908659086690867908689086990870908719087290873908749087590876908779087890879908809088190882908839088490885908869088790888908899089090891908929089390894908959089690897908989089990900909019090290903909049090590906909079090890909909109091190912909139091490915909169091790918909199092090921909229092390924909259092690927909289092990930909319093290933909349093590936909379093890939909409094190942909439094490945909469094790948909499095090951909529095390954909559095690957909589095990960909619096290963909649096590966909679096890969909709097190972909739097490975909769097790978909799098090981909829098390984909859098690987909889098990990909919099290993909949099590996909979099890999910009100191002910039100491005910069100791008910099101091011910129101391014910159101691017910189101991020910219102291023910249102591026910279102891029910309103191032910339103491035910369103791038910399104091041910429104391044910459104691047910489104991050910519105291053910549105591056910579105891059910609106191062910639106491065910669106791068910699107091071910729107391074910759107691077910789107991080910819108291083910849108591086910879108891089910909109191092910939109491095910969109791098910999110091101911029110391104911059110691107911089110991110911119111291113911149111591116911179111891119911209112191122911239112491125911269112791128911299113091131911329113391134911359113691137911389113991140911419114291143911449114591146911479114891149911509115191152911539115491155911569115791158911599116091161911629116391164911659116691167911689116991170911719117291173911749117591176911779117891179911809118191182911839118491185911869118791188911899119091191911929119391194911959119691197911989119991200912019120291203912049120591206912079120891209912109121191212912139121491215912169121791218912199122091221912229122391224912259122691227912289122991230912319123291233912349123591236912379123891239912409124191242912439124491245912469124791248912499125091251912529125391254912559125691257912589125991260912619126291263912649126591266912679126891269912709127191272912739127491275912769127791278912799128091281912829128391284912859128691287912889128991290912919129291293912949129591296912979129891299913009130191302913039130491305913069130791308913099131091311913129131391314913159131691317913189131991320913219132291323913249132591326913279132891329913309133191332913339133491335913369133791338913399134091341913429134391344913459134691347913489134991350913519135291353913549135591356913579135891359913609136191362913639136491365913669136791368913699137091371913729137391374913759137691377913789137991380913819138291383913849138591386913879138891389913909139191392913939139491395913969139791398913999140091401914029140391404914059140691407914089140991410914119141291413914149141591416914179141891419914209142191422914239142491425914269142791428914299143091431914329143391434914359143691437914389143991440914419144291443914449144591446914479144891449914509145191452914539145491455914569145791458914599146091461914629146391464914659146691467914689146991470914719147291473914749147591476914779147891479914809148191482914839148491485914869148791488914899149091491914929149391494914959149691497914989149991500915019150291503915049150591506915079150891509915109151191512915139151491515915169151791518915199152091521915229152391524915259152691527915289152991530915319153291533915349153591536915379153891539915409154191542915439154491545915469154791548915499155091551915529155391554915559155691557915589155991560915619156291563915649156591566915679156891569915709157191572915739157491575915769157791578915799158091581915829158391584915859158691587915889158991590915919159291593915949159591596915979159891599916009160191602916039160491605916069160791608916099161091611916129161391614916159161691617916189161991620916219162291623916249162591626916279162891629916309163191632916339163491635916369163791638916399164091641916429164391644916459164691647916489164991650916519165291653916549165591656916579165891659916609166191662916639166491665916669166791668916699167091671916729167391674916759167691677916789167991680916819168291683916849168591686916879168891689916909169191692916939169491695916969169791698916999170091701917029170391704917059170691707917089170991710917119171291713917149171591716917179171891719917209172191722917239172491725917269172791728917299173091731917329173391734917359173691737917389173991740917419174291743917449174591746917479174891749917509175191752917539175491755917569175791758917599176091761917629176391764917659176691767917689176991770917719177291773917749177591776917779177891779917809178191782917839178491785917869178791788917899179091791917929179391794917959179691797917989179991800918019180291803918049180591806918079180891809918109181191812918139181491815918169181791818918199182091821918229182391824918259182691827918289182991830918319183291833918349183591836918379183891839918409184191842918439184491845918469184791848918499185091851918529185391854918559185691857918589185991860918619186291863918649186591866918679186891869918709187191872918739187491875918769187791878918799188091881918829188391884918859188691887918889188991890918919189291893918949189591896918979189891899919009190191902919039190491905919069190791908919099191091911919129191391914919159191691917919189191991920919219192291923919249192591926919279192891929919309193191932919339193491935919369193791938919399194091941919429194391944919459194691947919489194991950919519195291953919549195591956919579195891959919609196191962919639196491965919669196791968919699197091971919729197391974919759197691977919789197991980919819198291983919849198591986919879198891989919909199191992919939199491995919969199791998919999200092001920029200392004920059200692007920089200992010920119201292013920149201592016920179201892019920209202192022920239202492025920269202792028920299203092031920329203392034920359203692037920389203992040920419204292043920449204592046920479204892049920509205192052920539205492055920569205792058920599206092061920629206392064920659206692067920689206992070920719207292073920749207592076920779207892079920809208192082920839208492085920869208792088920899209092091920929209392094920959209692097920989209992100921019210292103921049210592106921079210892109921109211192112921139211492115921169211792118921199212092121921229212392124921259212692127921289212992130921319213292133921349213592136921379213892139921409214192142921439214492145921469214792148921499215092151921529215392154921559215692157921589215992160921619216292163921649216592166921679216892169921709217192172921739217492175921769217792178921799218092181921829218392184921859218692187921889218992190921919219292193921949219592196921979219892199922009220192202922039220492205922069220792208922099221092211922129221392214922159221692217922189221992220922219222292223922249222592226922279222892229922309223192232922339223492235922369223792238922399224092241922429224392244922459224692247922489224992250922519225292253922549225592256922579225892259922609226192262922639226492265922669226792268922699227092271922729227392274922759227692277922789227992280922819228292283922849228592286922879228892289922909229192292922939229492295922969229792298922999230092301923029230392304923059230692307923089230992310923119231292313923149231592316923179231892319923209232192322923239232492325923269232792328923299233092331923329233392334923359233692337923389233992340923419234292343923449234592346923479234892349923509235192352923539235492355923569235792358923599236092361923629236392364923659236692367923689236992370923719237292373923749237592376923779237892379923809238192382923839238492385923869238792388923899239092391923929239392394923959239692397923989239992400924019240292403924049240592406924079240892409924109241192412924139241492415924169241792418924199242092421924229242392424924259242692427924289242992430924319243292433924349243592436924379243892439924409244192442924439244492445924469244792448924499245092451924529245392454924559245692457924589245992460924619246292463924649246592466924679246892469924709247192472924739247492475924769247792478924799248092481924829248392484924859248692487924889248992490924919249292493924949249592496924979249892499925009250192502925039250492505925069250792508925099251092511925129251392514925159251692517925189251992520925219252292523925249252592526925279252892529925309253192532925339253492535925369253792538925399254092541925429254392544925459254692547925489254992550925519255292553925549255592556925579255892559925609256192562925639256492565925669256792568925699257092571925729257392574925759257692577925789257992580925819258292583925849258592586925879258892589925909259192592925939259492595925969259792598925999260092601926029260392604926059260692607926089260992610926119261292613926149261592616926179261892619926209262192622926239262492625926269262792628926299263092631926329263392634926359263692637926389263992640926419264292643926449264592646926479264892649926509265192652926539265492655926569265792658926599266092661926629266392664926659266692667926689266992670926719267292673926749267592676926779267892679926809268192682926839268492685926869268792688926899269092691926929269392694926959269692697926989269992700927019270292703927049270592706927079270892709927109271192712927139271492715927169271792718927199272092721927229272392724927259272692727927289272992730927319273292733927349273592736927379273892739927409274192742927439274492745927469274792748927499275092751927529275392754927559275692757927589275992760927619276292763927649276592766927679276892769927709277192772927739277492775927769277792778927799278092781927829278392784927859278692787927889278992790927919279292793927949279592796927979279892799928009280192802928039280492805928069280792808928099281092811928129281392814928159281692817928189281992820928219282292823928249282592826928279282892829928309283192832928339283492835928369283792838928399284092841928429284392844928459284692847928489284992850928519285292853928549285592856928579285892859928609286192862928639286492865928669286792868928699287092871928729287392874928759287692877928789287992880928819288292883928849288592886928879288892889928909289192892928939289492895928969289792898928999290092901929029290392904929059290692907929089290992910929119291292913929149291592916929179291892919929209292192922929239292492925929269292792928929299293092931929329293392934929359293692937929389293992940929419294292943929449294592946929479294892949929509295192952929539295492955929569295792958929599296092961929629296392964929659296692967929689296992970929719297292973929749297592976929779297892979929809298192982929839298492985929869298792988929899299092991929929299392994929959299692997929989299993000930019300293003930049300593006930079300893009930109301193012930139301493015930169301793018930199302093021930229302393024930259302693027930289302993030930319303293033930349303593036930379303893039930409304193042930439304493045930469304793048930499305093051930529305393054930559305693057930589305993060930619306293063930649306593066930679306893069930709307193072930739307493075930769307793078930799308093081930829308393084930859308693087930889308993090930919309293093930949309593096930979309893099931009310193102931039310493105931069310793108931099311093111931129311393114931159311693117931189311993120931219312293123931249312593126931279312893129931309313193132931339313493135931369313793138931399314093141931429314393144931459314693147931489314993150931519315293153931549315593156931579315893159931609316193162931639316493165931669316793168931699317093171931729317393174931759317693177931789317993180931819318293183931849318593186931879318893189931909319193192931939319493195931969319793198931999320093201932029320393204932059320693207932089320993210932119321293213932149321593216932179321893219932209322193222932239322493225932269322793228932299323093231932329323393234932359323693237932389323993240932419324293243932449324593246932479324893249932509325193252932539325493255932569325793258932599326093261932629326393264932659326693267932689326993270932719327293273932749327593276932779327893279932809328193282932839328493285932869328793288932899329093291932929329393294932959329693297932989329993300933019330293303933049330593306933079330893309933109331193312933139331493315933169331793318933199332093321933229332393324933259332693327933289332993330933319333293333933349333593336933379333893339933409334193342933439334493345933469334793348933499335093351933529335393354933559335693357933589335993360933619336293363933649336593366933679336893369933709337193372933739337493375933769337793378933799338093381933829338393384933859338693387933889338993390933919339293393933949339593396933979339893399934009340193402934039340493405934069340793408934099341093411934129341393414934159341693417934189341993420934219342293423934249342593426934279342893429934309343193432934339343493435934369343793438934399344093441934429344393444934459344693447934489344993450934519345293453934549345593456934579345893459934609346193462934639346493465934669346793468934699347093471934729347393474934759347693477934789347993480934819348293483934849348593486934879348893489934909349193492934939349493495934969349793498934999350093501935029350393504935059350693507935089350993510935119351293513935149351593516935179351893519935209352193522935239352493525935269352793528935299353093531935329353393534935359353693537935389353993540935419354293543935449354593546935479354893549935509355193552935539355493555935569355793558935599356093561935629356393564935659356693567935689356993570935719357293573935749357593576935779357893579935809358193582935839358493585935869358793588935899359093591935929359393594935959359693597935989359993600936019360293603936049360593606936079360893609936109361193612936139361493615936169361793618936199362093621936229362393624936259362693627936289362993630936319363293633936349363593636936379363893639936409364193642936439364493645936469364793648936499365093651936529365393654936559365693657936589365993660936619366293663936649366593666936679366893669936709367193672936739367493675936769367793678936799368093681936829368393684936859368693687936889368993690936919369293693936949369593696936979369893699937009370193702937039370493705937069370793708937099371093711937129371393714937159371693717937189371993720937219372293723937249372593726937279372893729937309373193732937339373493735937369373793738937399374093741937429374393744937459374693747937489374993750937519375293753937549375593756937579375893759937609376193762937639376493765937669376793768937699377093771937729377393774937759377693777937789377993780937819378293783937849378593786937879378893789937909379193792937939379493795937969379793798937999380093801938029380393804938059380693807938089380993810938119381293813938149381593816938179381893819938209382193822938239382493825938269382793828938299383093831938329383393834938359383693837938389383993840938419384293843938449384593846938479384893849938509385193852938539385493855938569385793858938599386093861938629386393864938659386693867938689386993870938719387293873938749387593876938779387893879938809388193882938839388493885938869388793888938899389093891938929389393894938959389693897938989389993900939019390293903939049390593906939079390893909939109391193912939139391493915939169391793918939199392093921939229392393924939259392693927939289392993930939319393293933939349393593936939379393893939939409394193942939439394493945939469394793948939499395093951939529395393954939559395693957939589395993960939619396293963939649396593966939679396893969939709397193972939739397493975939769397793978939799398093981939829398393984939859398693987939889398993990939919399293993939949399593996939979399893999940009400194002940039400494005940069400794008940099401094011940129401394014940159401694017940189401994020940219402294023940249402594026940279402894029940309403194032940339403494035940369403794038940399404094041940429404394044940459404694047940489404994050940519405294053940549405594056940579405894059940609406194062940639406494065940669406794068940699407094071940729407394074940759407694077940789407994080940819408294083940849408594086940879408894089940909409194092940939409494095940969409794098940999410094101941029410394104941059410694107941089410994110941119411294113941149411594116941179411894119941209412194122941239412494125941269412794128941299413094131941329413394134941359413694137941389413994140941419414294143941449414594146941479414894149941509415194152941539415494155941569415794158941599416094161941629416394164941659416694167941689416994170941719417294173941749417594176941779417894179941809418194182941839418494185941869418794188941899419094191941929419394194941959419694197941989419994200942019420294203942049420594206942079420894209942109421194212942139421494215942169421794218942199422094221942229422394224942259422694227942289422994230942319423294233942349423594236942379423894239942409424194242942439424494245942469424794248942499425094251942529425394254942559425694257942589425994260942619426294263942649426594266942679426894269942709427194272942739427494275942769427794278942799428094281942829428394284942859428694287942889428994290942919429294293942949429594296942979429894299943009430194302943039430494305943069430794308943099431094311943129431394314943159431694317943189431994320943219432294323943249432594326943279432894329943309433194332943339433494335943369433794338943399434094341943429434394344943459434694347943489434994350943519435294353943549435594356943579435894359943609436194362943639436494365943669436794368943699437094371943729437394374943759437694377943789437994380943819438294383943849438594386943879438894389943909439194392943939439494395943969439794398943999440094401944029440394404944059440694407944089440994410944119441294413944149441594416944179441894419944209442194422944239442494425944269442794428944299443094431944329443394434944359443694437944389443994440944419444294443944449444594446944479444894449944509445194452944539445494455944569445794458944599446094461944629446394464944659446694467944689446994470944719447294473944749447594476944779447894479944809448194482944839448494485944869448794488944899449094491944929449394494944959449694497944989449994500945019450294503945049450594506945079450894509945109451194512945139451494515945169451794518945199452094521945229452394524945259452694527945289452994530945319453294533945349453594536945379453894539945409454194542945439454494545945469454794548945499455094551945529455394554945559455694557945589455994560945619456294563945649456594566945679456894569945709457194572945739457494575945769457794578945799458094581945829458394584945859458694587945889458994590945919459294593945949459594596945979459894599946009460194602946039460494605946069460794608946099461094611946129461394614946159461694617946189461994620946219462294623946249462594626946279462894629946309463194632946339463494635946369463794638946399464094641946429464394644946459464694647946489464994650946519465294653946549465594656946579465894659946609466194662946639466494665946669466794668946699467094671946729467394674946759467694677946789467994680946819468294683946849468594686946879468894689946909469194692946939469494695946969469794698946999470094701947029470394704947059470694707947089470994710947119471294713947149471594716947179471894719947209472194722947239472494725947269472794728947299473094731947329473394734947359473694737947389473994740947419474294743947449474594746947479474894749947509475194752947539475494755947569475794758947599476094761947629476394764947659476694767947689476994770947719477294773947749477594776947779477894779947809478194782947839478494785947869478794788947899479094791947929479394794947959479694797947989479994800948019480294803948049480594806948079480894809948109481194812948139481494815948169481794818948199482094821948229482394824948259482694827948289482994830948319483294833948349483594836948379483894839948409484194842948439484494845948469484794848948499485094851948529485394854948559485694857948589485994860948619486294863948649486594866948679486894869948709487194872948739487494875948769487794878948799488094881948829488394884948859488694887948889488994890948919489294893948949489594896948979489894899949009490194902949039490494905949069490794908949099491094911949129491394914949159491694917949189491994920949219492294923949249492594926949279492894929949309493194932949339493494935949369493794938949399494094941949429494394944949459494694947949489494994950949519495294953949549495594956949579495894959949609496194962949639496494965949669496794968949699497094971949729497394974949759497694977949789497994980949819498294983949849498594986949879498894989949909499194992949939499494995949969499794998949999500095001950029500395004950059500695007950089500995010950119501295013950149501595016950179501895019950209502195022950239502495025950269502795028950299503095031950329503395034950359503695037950389503995040950419504295043950449504595046950479504895049950509505195052950539505495055950569505795058950599506095061950629506395064950659506695067950689506995070950719507295073950749507595076950779507895079950809508195082950839508495085950869508795088950899509095091950929509395094950959509695097950989509995100951019510295103951049510595106951079510895109951109511195112951139511495115951169511795118951199512095121951229512395124951259512695127951289512995130951319513295133951349513595136951379513895139951409514195142951439514495145951469514795148951499515095151951529515395154951559515695157951589515995160951619516295163951649516595166951679516895169951709517195172951739517495175951769517795178951799518095181951829518395184951859518695187951889518995190951919519295193951949519595196951979519895199952009520195202952039520495205952069520795208952099521095211952129521395214952159521695217952189521995220952219522295223952249522595226952279522895229952309523195232952339523495235952369523795238952399524095241952429524395244952459524695247952489524995250952519525295253952549525595256952579525895259952609526195262952639526495265952669526795268952699527095271952729527395274952759527695277952789527995280952819528295283952849528595286952879528895289952909529195292952939529495295952969529795298952999530095301953029530395304953059530695307953089530995310953119531295313953149531595316953179531895319953209532195322953239532495325953269532795328953299533095331953329533395334953359533695337953389533995340953419534295343953449534595346953479534895349953509535195352953539535495355953569535795358953599536095361953629536395364953659536695367953689536995370953719537295373953749537595376953779537895379953809538195382953839538495385953869538795388953899539095391953929539395394953959539695397953989539995400954019540295403954049540595406954079540895409954109541195412954139541495415954169541795418954199542095421954229542395424954259542695427954289542995430954319543295433954349543595436954379543895439954409544195442954439544495445954469544795448954499545095451954529545395454954559545695457954589545995460954619546295463954649546595466954679546895469954709547195472954739547495475954769547795478954799548095481954829548395484954859548695487954889548995490954919549295493954949549595496954979549895499955009550195502955039550495505955069550795508955099551095511955129551395514955159551695517955189551995520955219552295523955249552595526955279552895529955309553195532955339553495535955369553795538955399554095541955429554395544955459554695547955489554995550955519555295553955549555595556955579555895559955609556195562955639556495565955669556795568955699557095571955729557395574955759557695577955789557995580955819558295583955849558595586955879558895589955909559195592955939559495595955969559795598955999560095601956029560395604956059560695607956089560995610956119561295613956149561595616956179561895619956209562195622956239562495625956269562795628956299563095631956329563395634956359563695637956389563995640956419564295643956449564595646956479564895649956509565195652956539565495655956569565795658956599566095661956629566395664956659566695667956689566995670956719567295673956749567595676956779567895679956809568195682956839568495685956869568795688956899569095691956929569395694956959569695697956989569995700957019570295703957049570595706957079570895709957109571195712957139571495715957169571795718957199572095721957229572395724957259572695727957289572995730957319573295733957349573595736957379573895739957409574195742957439574495745957469574795748957499575095751957529575395754957559575695757957589575995760957619576295763957649576595766957679576895769957709577195772957739577495775957769577795778957799578095781957829578395784957859578695787957889578995790957919579295793957949579595796957979579895799958009580195802958039580495805958069580795808958099581095811958129581395814958159581695817958189581995820958219582295823958249582595826958279582895829958309583195832958339583495835958369583795838958399584095841958429584395844958459584695847958489584995850958519585295853958549585595856958579585895859958609586195862958639586495865958669586795868958699587095871958729587395874958759587695877958789587995880958819588295883958849588595886958879588895889958909589195892958939589495895958969589795898958999590095901959029590395904959059590695907959089590995910959119591295913959149591595916959179591895919959209592195922959239592495925959269592795928959299593095931959329593395934959359593695937959389593995940959419594295943959449594595946959479594895949959509595195952959539595495955959569595795958959599596095961959629596395964959659596695967959689596995970959719597295973959749597595976959779597895979959809598195982959839598495985959869598795988959899599095991959929599395994959959599695997959989599996000960019600296003960049600596006960079600896009960109601196012960139601496015960169601796018960199602096021960229602396024960259602696027960289602996030960319603296033960349603596036960379603896039960409604196042960439604496045960469604796048960499605096051960529605396054960559605696057960589605996060960619606296063960649606596066960679606896069960709607196072960739607496075960769607796078960799608096081960829608396084960859608696087960889608996090960919609296093960949609596096960979609896099961009610196102961039610496105961069610796108961099611096111961129611396114961159611696117961189611996120961219612296123961249612596126961279612896129961309613196132961339613496135961369613796138961399614096141961429614396144961459614696147961489614996150961519615296153961549615596156961579615896159961609616196162961639616496165961669616796168961699617096171961729617396174961759617696177961789617996180961819618296183961849618596186961879618896189961909619196192961939619496195961969619796198961999620096201962029620396204962059620696207962089620996210962119621296213962149621596216962179621896219962209622196222962239622496225962269622796228962299623096231962329623396234962359623696237962389623996240962419624296243962449624596246962479624896249962509625196252962539625496255962569625796258962599626096261962629626396264962659626696267962689626996270962719627296273962749627596276962779627896279962809628196282962839628496285962869628796288962899629096291962929629396294962959629696297962989629996300963019630296303963049630596306963079630896309963109631196312963139631496315963169631796318963199632096321963229632396324963259632696327963289632996330963319633296333963349633596336963379633896339963409634196342963439634496345963469634796348963499635096351963529635396354963559635696357963589635996360963619636296363963649636596366963679636896369963709637196372963739637496375963769637796378963799638096381963829638396384963859638696387963889638996390963919639296393963949639596396963979639896399964009640196402964039640496405964069640796408964099641096411964129641396414964159641696417964189641996420964219642296423964249642596426964279642896429964309643196432964339643496435964369643796438964399644096441964429644396444964459644696447964489644996450964519645296453964549645596456964579645896459964609646196462964639646496465964669646796468964699647096471964729647396474964759647696477964789647996480964819648296483964849648596486964879648896489964909649196492964939649496495964969649796498964999650096501965029650396504965059650696507965089650996510965119651296513965149651596516965179651896519965209652196522965239652496525965269652796528965299653096531965329653396534965359653696537965389653996540965419654296543965449654596546965479654896549965509655196552965539655496555965569655796558965599656096561965629656396564965659656696567965689656996570965719657296573965749657596576965779657896579965809658196582965839658496585965869658796588965899659096591965929659396594965959659696597965989659996600966019660296603966049660596606966079660896609966109661196612966139661496615966169661796618966199662096621966229662396624966259662696627966289662996630966319663296633966349663596636966379663896639966409664196642966439664496645966469664796648966499665096651966529665396654966559665696657966589665996660966619666296663966649666596666966679666896669966709667196672966739667496675966769667796678966799668096681966829668396684966859668696687966889668996690966919669296693966949669596696966979669896699967009670196702967039670496705967069670796708967099671096711967129671396714967159671696717967189671996720967219672296723967249672596726967279672896729967309673196732967339673496735967369673796738967399674096741967429674396744967459674696747967489674996750967519675296753967549675596756967579675896759967609676196762967639676496765967669676796768967699677096771967729677396774967759677696777967789677996780967819678296783967849678596786967879678896789967909679196792967939679496795967969679796798967999680096801968029680396804968059680696807968089680996810968119681296813968149681596816968179681896819968209682196822968239682496825968269682796828968299683096831968329683396834968359683696837968389683996840968419684296843968449684596846968479684896849968509685196852968539685496855968569685796858968599686096861968629686396864968659686696867968689686996870968719687296873968749687596876968779687896879968809688196882968839688496885968869688796888968899689096891968929689396894968959689696897968989689996900969019690296903969049690596906969079690896909969109691196912969139691496915969169691796918969199692096921969229692396924969259692696927969289692996930969319693296933969349693596936969379693896939969409694196942969439694496945969469694796948969499695096951969529695396954969559695696957969589695996960969619696296963969649696596966969679696896969969709697196972969739697496975969769697796978969799698096981969829698396984969859698696987969889698996990969919699296993969949699596996969979699896999970009700197002970039700497005970069700797008970099701097011970129701397014970159701697017970189701997020970219702297023970249702597026970279702897029970309703197032970339703497035970369703797038970399704097041970429704397044970459704697047970489704997050970519705297053970549705597056970579705897059970609706197062970639706497065970669706797068970699707097071970729707397074970759707697077970789707997080970819708297083970849708597086970879708897089970909709197092970939709497095970969709797098970999710097101971029710397104971059710697107971089710997110971119711297113971149711597116971179711897119971209712197122971239712497125971269712797128971299713097131971329713397134971359713697137971389713997140971419714297143971449714597146971479714897149971509715197152971539715497155971569715797158971599716097161971629716397164971659716697167971689716997170971719717297173971749717597176971779717897179971809718197182971839718497185971869718797188971899719097191971929719397194971959719697197971989719997200972019720297203972049720597206972079720897209972109721197212972139721497215972169721797218972199722097221972229722397224972259722697227972289722997230972319723297233972349723597236972379723897239972409724197242972439724497245972469724797248972499725097251972529725397254972559725697257972589725997260972619726297263972649726597266972679726897269972709727197272972739727497275972769727797278972799728097281972829728397284972859728697287972889728997290972919729297293972949729597296972979729897299973009730197302973039730497305973069730797308973099731097311973129731397314973159731697317973189731997320973219732297323973249732597326973279732897329973309733197332973339733497335973369733797338973399734097341973429734397344973459734697347973489734997350973519735297353973549735597356973579735897359973609736197362973639736497365973669736797368973699737097371973729737397374973759737697377973789737997380973819738297383973849738597386973879738897389973909739197392973939739497395973969739797398973999740097401974029740397404974059740697407974089740997410974119741297413974149741597416974179741897419974209742197422974239742497425974269742797428974299743097431974329743397434974359743697437974389743997440974419744297443974449744597446974479744897449974509745197452974539745497455974569745797458974599746097461974629746397464974659746697467974689746997470974719747297473974749747597476974779747897479974809748197482974839748497485974869748797488974899749097491974929749397494974959749697497974989749997500975019750297503975049750597506975079750897509975109751197512975139751497515975169751797518975199752097521975229752397524975259752697527975289752997530975319753297533975349753597536975379753897539975409754197542975439754497545975469754797548975499755097551975529755397554975559755697557975589755997560975619756297563975649756597566975679756897569975709757197572975739757497575975769757797578975799758097581975829758397584975859758697587975889758997590975919759297593975949759597596975979759897599976009760197602976039760497605976069760797608976099761097611976129761397614976159761697617976189761997620976219762297623976249762597626976279762897629976309763197632976339763497635976369763797638976399764097641976429764397644976459764697647976489764997650976519765297653976549765597656976579765897659976609766197662976639766497665976669766797668976699767097671976729767397674976759767697677976789767997680976819768297683976849768597686976879768897689976909769197692976939769497695976969769797698976999770097701977029770397704977059770697707977089770997710977119771297713977149771597716977179771897719977209772197722977239772497725977269772797728977299773097731977329773397734977359773697737977389773997740977419774297743977449774597746977479774897749977509775197752977539775497755977569775797758977599776097761977629776397764977659776697767977689776997770977719777297773977749777597776977779777897779977809778197782977839778497785977869778797788977899779097791977929779397794977959779697797977989779997800978019780297803978049780597806978079780897809978109781197812978139781497815978169781797818978199782097821978229782397824978259782697827978289782997830978319783297833978349783597836978379783897839978409784197842978439784497845978469784797848978499785097851978529785397854978559785697857978589785997860978619786297863978649786597866978679786897869978709787197872978739787497875978769787797878978799788097881978829788397884978859788697887978889788997890978919789297893978949789597896978979789897899979009790197902979039790497905979069790797908979099791097911979129791397914979159791697917979189791997920979219792297923979249792597926979279792897929979309793197932979339793497935979369793797938979399794097941979429794397944979459794697947979489794997950979519795297953979549795597956979579795897959979609796197962979639796497965979669796797968979699797097971979729797397974979759797697977979789797997980979819798297983979849798597986979879798897989979909799197992979939799497995979969799797998979999800098001980029800398004980059800698007980089800998010980119801298013980149801598016980179801898019980209802198022980239802498025980269802798028980299803098031980329803398034980359803698037980389803998040980419804298043980449804598046980479804898049980509805198052980539805498055980569805798058980599806098061980629806398064980659806698067980689806998070980719807298073980749807598076980779807898079980809808198082980839808498085980869808798088980899809098091980929809398094980959809698097980989809998100981019810298103981049810598106981079810898109981109811198112981139811498115981169811798118981199812098121981229812398124981259812698127981289812998130981319813298133981349813598136981379813898139981409814198142981439814498145981469814798148981499815098151981529815398154981559815698157981589815998160981619816298163981649816598166981679816898169981709817198172981739817498175981769817798178981799818098181981829818398184981859818698187981889818998190981919819298193981949819598196981979819898199982009820198202982039820498205982069820798208982099821098211982129821398214982159821698217982189821998220982219822298223982249822598226982279822898229982309823198232982339823498235982369823798238982399824098241982429824398244982459824698247982489824998250982519825298253982549825598256982579825898259982609826198262982639826498265982669826798268982699827098271982729827398274982759827698277982789827998280982819828298283982849828598286982879828898289982909829198292982939829498295982969829798298982999830098301983029830398304983059830698307983089830998310983119831298313983149831598316983179831898319983209832198322983239832498325983269832798328983299833098331983329833398334983359833698337983389833998340983419834298343983449834598346983479834898349983509835198352983539835498355983569835798358983599836098361983629836398364983659836698367983689836998370983719837298373983749837598376983779837898379983809838198382983839838498385983869838798388983899839098391983929839398394983959839698397983989839998400984019840298403984049840598406984079840898409984109841198412984139841498415984169841798418984199842098421984229842398424984259842698427984289842998430984319843298433984349843598436984379843898439984409844198442984439844498445984469844798448984499845098451984529845398454984559845698457984589845998460984619846298463984649846598466984679846898469984709847198472984739847498475984769847798478984799848098481984829848398484984859848698487984889848998490984919849298493984949849598496984979849898499985009850198502985039850498505985069850798508985099851098511985129851398514985159851698517985189851998520985219852298523985249852598526985279852898529985309853198532985339853498535985369853798538985399854098541985429854398544985459854698547985489854998550985519855298553985549855598556985579855898559985609856198562985639856498565985669856798568985699857098571985729857398574985759857698577985789857998580985819858298583985849858598586985879858898589985909859198592985939859498595985969859798598985999860098601986029860398604986059860698607986089860998610986119861298613986149861598616986179861898619986209862198622986239862498625986269862798628986299863098631986329863398634986359863698637986389863998640986419864298643986449864598646986479864898649986509865198652986539865498655986569865798658986599866098661986629866398664986659866698667986689866998670986719867298673986749867598676986779867898679986809868198682986839868498685986869868798688986899869098691986929869398694986959869698697986989869998700987019870298703987049870598706987079870898709987109871198712987139871498715987169871798718987199872098721987229872398724987259872698727987289872998730987319873298733987349873598736987379873898739987409874198742987439874498745987469874798748987499875098751987529875398754987559875698757987589875998760987619876298763987649876598766987679876898769987709877198772987739877498775987769877798778987799878098781987829878398784987859878698787987889878998790987919879298793987949879598796987979879898799988009880198802988039880498805988069880798808988099881098811988129881398814988159881698817988189881998820988219882298823988249882598826988279882898829988309883198832988339883498835988369883798838988399884098841988429884398844988459884698847988489884998850988519885298853988549885598856988579885898859988609886198862988639886498865988669886798868988699887098871988729887398874988759887698877988789887998880988819888298883988849888598886988879888898889988909889198892988939889498895988969889798898988999890098901989029890398904989059890698907989089890998910989119891298913989149891598916989179891898919989209892198922989239892498925989269892798928989299893098931989329893398934989359893698937989389893998940989419894298943989449894598946989479894898949989509895198952989539895498955989569895798958989599896098961989629896398964989659896698967989689896998970989719897298973989749897598976989779897898979989809898198982989839898498985989869898798988989899899098991989929899398994989959899698997989989899999000990019900299003990049900599006990079900899009990109901199012990139901499015990169901799018990199902099021990229902399024990259902699027990289902999030990319903299033990349903599036990379903899039990409904199042990439904499045990469904799048990499905099051990529905399054990559905699057990589905999060990619906299063990649906599066990679906899069990709907199072990739907499075990769907799078990799908099081990829908399084990859908699087990889908999090990919909299093990949909599096990979909899099991009910199102991039910499105991069910799108991099911099111991129911399114991159911699117991189911999120991219912299123991249912599126991279912899129991309913199132991339913499135991369913799138991399914099141991429914399144991459914699147991489914999150991519915299153991549915599156991579915899159991609916199162991639916499165991669916799168991699917099171991729917399174991759917699177991789917999180991819918299183991849918599186991879918899189991909919199192991939919499195991969919799198991999920099201992029920399204992059920699207992089920999210992119921299213992149921599216992179921899219992209922199222992239922499225992269922799228992299923099231992329923399234992359923699237992389923999240992419924299243992449924599246992479924899249992509925199252992539925499255992569925799258992599926099261992629926399264992659926699267992689926999270992719927299273992749927599276992779927899279992809928199282992839928499285992869928799288992899929099291992929929399294992959929699297992989929999300993019930299303993049930599306993079930899309993109931199312993139931499315993169931799318993199932099321993229932399324993259932699327993289932999330993319933299333993349933599336993379933899339993409934199342993439934499345993469934799348993499935099351993529935399354993559935699357993589935999360993619936299363993649936599366993679936899369993709937199372993739937499375993769937799378993799938099381993829938399384993859938699387993889938999390993919939299393993949939599396993979939899399994009940199402994039940499405994069940799408994099941099411994129941399414994159941699417994189941999420994219942299423994249942599426994279942899429994309943199432994339943499435994369943799438994399944099441994429944399444994459944699447994489944999450994519945299453994549945599456994579945899459994609946199462994639946499465994669946799468994699947099471994729947399474994759947699477994789947999480994819948299483994849948599486994879948899489994909949199492994939949499495994969949799498994999950099501995029950399504995059950699507995089950999510995119951299513995149951599516995179951899519995209952199522995239952499525995269952799528995299953099531995329953399534995359953699537995389953999540995419954299543995449954599546995479954899549995509955199552995539955499555995569955799558995599956099561995629956399564995659956699567995689956999570995719957299573995749957599576995779957899579995809958199582995839958499585995869958799588995899959099591995929959399594995959959699597995989959999600996019960299603996049960599606996079960899609996109961199612996139961499615996169961799618996199962099621996229962399624996259962699627996289962999630996319963299633996349963599636996379963899639996409964199642996439964499645996469964799648996499965099651996529965399654996559965699657996589965999660996619966299663996649966599666996679966899669996709967199672996739967499675996769967799678996799968099681996829968399684996859968699687996889968999690996919969299693996949969599696996979969899699997009970199702997039970499705997069970799708997099971099711997129971399714997159971699717997189971999720997219972299723997249972599726997279972899729997309973199732997339973499735997369973799738997399974099741997429974399744997459974699747997489974999750997519975299753997549975599756997579975899759997609976199762997639976499765997669976799768997699977099771997729977399774997759977699777997789977999780997819978299783997849978599786997879978899789997909979199792997939979499795997969979799798997999980099801998029980399804998059980699807998089980999810998119981299813998149981599816998179981899819998209982199822998239982499825998269982799828998299983099831998329983399834998359983699837998389983999840998419984299843998449984599846998479984899849998509985199852998539985499855998569985799858998599986099861998629986399864998659986699867998689986999870998719987299873998749987599876998779987899879998809988199882998839988499885998869988799888998899989099891998929989399894998959989699897998989989999900999019990299903999049990599906999079990899909999109991199912999139991499915999169991799918999199992099921999229992399924999259992699927999289992999930999319993299933999349993599936999379993899939999409994199942999439994499945999469994799948999499995099951999529995399954999559995699957999589995999960999619996299963999649996599966999679996899969999709997199972999739997499975999769997799978999799998099981999829998399984999859998699987999889998999990999919999299993999949999599996999979999899999100000100001100002100003100004100005100006100007100008100009100010100011100012100013100014100015100016100017100018100019100020100021100022100023100024100025100026100027100028100029100030100031100032100033100034100035100036100037100038100039100040100041100042100043100044100045100046100047100048100049100050100051100052100053100054100055100056100057100058100059100060100061100062100063100064100065100066100067100068100069100070100071100072100073100074100075100076100077100078100079100080100081100082100083100084100085100086100087100088100089100090100091100092100093100094100095100096100097100098100099100100100101100102100103100104100105100106100107100108100109100110100111100112100113100114100115100116100117100118100119100120100121100122100123100124100125100126100127100128100129100130100131100132100133100134100135100136100137100138100139100140100141100142100143100144100145100146100147100148100149100150100151100152100153100154100155100156100157100158100159100160100161100162100163100164100165100166100167100168100169100170100171100172100173100174100175100176100177100178100179100180100181100182100183100184100185100186100187100188100189100190100191100192100193100194100195100196100197100198100199100200100201100202100203100204100205100206100207100208100209100210100211100212100213100214100215100216100217100218100219100220100221100222100223100224100225100226100227100228100229100230100231100232100233100234100235100236100237100238100239100240100241100242100243100244100245100246100247100248100249100250100251100252100253100254100255100256100257100258100259100260100261100262100263100264100265100266100267100268100269100270100271100272100273100274100275100276100277100278100279100280100281100282100283100284100285100286100287100288100289100290100291100292100293100294100295100296100297100298100299100300100301100302100303100304100305100306100307100308100309100310100311100312100313100314100315100316100317100318100319100320100321100322100323100324100325100326100327100328100329100330100331100332100333100334100335100336100337100338100339100340100341100342100343100344100345100346100347100348100349100350100351100352100353100354100355100356100357100358100359100360100361100362100363100364100365100366100367100368100369100370100371100372100373100374100375100376100377100378100379100380100381100382100383100384100385100386100387100388100389100390100391100392100393100394100395100396100397100398100399100400100401100402100403100404100405100406100407100408100409100410100411100412100413100414100415100416100417100418100419100420100421100422100423100424100425100426100427100428100429100430100431100432100433100434100435100436100437100438100439100440100441100442100443100444100445100446100447100448100449100450100451100452100453100454100455100456100457100458100459100460100461100462100463100464100465100466100467100468100469100470100471100472100473100474100475100476100477100478100479100480100481100482100483100484100485100486100487100488100489100490100491100492100493100494100495100496100497100498100499100500100501100502100503100504100505100506100507100508100509100510100511100512100513100514100515100516100517100518100519100520100521100522100523100524100525100526100527100528100529100530100531100532100533100534100535100536100537100538100539100540100541100542100543100544100545100546100547100548100549100550100551100552100553100554100555100556100557100558100559100560100561100562100563100564100565100566100567100568100569100570100571100572100573100574100575100576100577100578100579100580100581100582100583100584100585100586100587100588100589100590100591100592100593100594100595100596100597100598100599100600100601100602100603100604100605100606100607100608100609100610100611100612100613100614100615100616100617100618100619100620100621100622100623100624100625100626100627100628100629100630100631100632100633100634100635100636100637100638100639100640100641100642100643100644100645100646100647100648100649100650100651100652100653100654100655100656100657100658100659100660100661100662100663100664100665100666100667100668100669100670100671100672100673100674100675100676100677100678100679100680100681100682100683100684100685100686100687100688100689100690100691100692100693100694100695100696100697100698100699100700100701100702100703100704100705100706100707100708100709100710100711100712100713100714100715100716100717100718100719100720100721100722100723100724100725100726100727100728100729100730100731100732100733100734100735100736100737100738100739100740100741100742100743100744100745100746100747100748100749100750100751100752100753100754100755100756100757100758100759100760100761100762100763100764100765100766100767100768100769100770100771100772100773100774100775100776100777100778100779100780100781100782100783100784100785100786100787100788100789100790100791100792100793100794100795100796100797100798100799100800100801100802100803100804100805100806100807100808100809100810100811100812100813100814100815100816100817100818100819100820100821100822100823100824100825100826100827100828100829100830100831100832100833100834100835100836100837100838100839100840100841100842100843100844100845100846100847100848100849100850100851100852100853100854100855100856100857100858100859100860100861100862100863100864100865100866100867100868100869100870100871100872100873100874100875100876100877100878100879100880100881100882100883100884100885100886100887100888100889100890100891100892100893100894100895100896100897100898100899100900100901100902100903100904100905100906100907100908100909100910100911100912100913100914100915100916100917100918100919100920100921100922100923100924100925100926100927100928100929100930100931100932100933100934100935100936100937100938100939100940100941100942100943100944100945100946100947100948100949100950100951100952100953100954100955100956100957100958100959100960100961100962100963100964100965100966100967100968100969100970100971100972100973100974100975100976100977100978100979100980100981100982100983100984100985100986100987100988100989100990100991100992100993100994100995100996100997100998100999101000101001101002101003101004101005101006101007101008101009101010101011101012101013101014101015101016101017101018101019101020101021101022101023101024101025101026101027101028101029101030101031101032101033101034101035101036101037101038101039101040101041101042101043101044101045101046101047101048101049101050101051101052101053101054101055101056101057101058101059101060101061101062101063101064101065101066101067101068101069101070101071101072101073101074101075101076101077101078101079101080101081101082101083101084101085101086101087101088101089101090101091101092101093101094101095101096101097101098101099101100101101101102101103101104101105101106101107101108101109101110101111101112101113101114101115101116101117101118101119101120101121101122101123101124101125101126101127101128101129101130101131101132101133101134101135101136101137101138101139101140101141101142101143101144101145101146101147101148101149101150101151101152101153101154101155101156101157101158101159101160101161101162101163101164101165101166101167101168101169101170101171101172101173101174101175101176101177101178101179101180101181101182101183101184101185101186101187101188101189101190101191101192101193101194101195101196101197101198101199101200101201101202101203101204101205101206101207101208101209101210101211101212101213101214101215101216101217101218101219101220101221101222101223101224101225101226101227101228101229101230101231101232101233101234101235101236101237101238101239101240101241101242101243101244101245101246101247101248101249101250101251101252101253101254101255101256101257101258101259101260101261101262101263101264101265101266101267101268101269101270101271101272101273101274101275101276101277101278101279101280101281101282101283101284101285101286101287101288101289101290101291101292101293101294101295101296101297101298101299101300101301101302101303101304101305101306101307101308101309101310101311101312101313101314101315101316101317101318101319101320101321101322101323101324101325101326101327101328101329101330101331101332101333101334101335101336101337101338101339101340101341101342101343101344101345101346101347101348101349101350101351101352101353101354101355101356101357101358101359101360101361101362101363101364101365101366101367101368101369101370101371101372101373101374101375101376101377101378101379101380101381101382101383101384101385101386101387101388101389101390101391101392101393101394101395101396101397101398101399101400101401101402101403101404101405101406101407101408101409101410101411101412101413101414101415101416101417101418101419101420101421101422101423101424101425101426101427101428101429101430101431101432101433101434101435101436101437101438101439101440101441101442101443101444101445101446101447101448101449101450101451101452101453101454101455101456101457101458101459101460101461101462101463101464101465101466101467101468101469101470101471101472101473101474101475101476101477101478101479101480101481101482101483101484101485101486101487101488101489101490101491101492101493101494101495101496101497101498101499101500101501101502101503101504101505101506101507101508101509101510101511101512101513101514101515101516101517101518101519101520101521101522101523101524101525101526101527101528101529101530101531101532101533101534101535101536101537101538101539101540101541101542101543101544101545101546101547101548101549101550101551101552101553101554101555101556101557101558101559101560101561101562101563101564101565101566101567101568101569101570101571101572101573101574101575101576101577101578101579101580101581101582101583101584101585101586101587101588101589101590101591101592101593101594101595101596101597101598101599101600101601101602101603101604101605101606101607101608101609101610101611101612101613101614101615101616101617101618101619101620101621101622101623101624101625101626101627101628101629101630101631101632101633101634101635101636101637101638101639101640101641101642101643101644101645101646101647101648101649101650101651101652101653101654101655101656101657101658101659101660101661101662101663101664101665101666101667101668101669101670101671101672101673101674101675101676101677101678101679101680101681101682101683101684101685101686101687101688101689101690101691101692101693101694101695101696101697101698101699101700101701101702101703101704101705101706101707101708101709101710101711101712101713101714101715101716101717101718101719101720101721101722101723101724101725101726101727101728101729101730101731101732101733101734101735101736101737101738101739101740101741101742101743101744101745101746101747101748101749101750101751101752101753101754101755101756101757101758101759101760101761101762101763101764101765101766101767101768101769101770101771101772101773101774101775101776101777101778101779101780101781101782101783101784101785101786101787101788101789101790101791101792101793101794101795101796101797101798101799101800101801101802101803101804101805101806101807101808101809101810101811101812101813101814101815101816101817101818101819101820101821101822101823101824101825101826101827101828101829101830101831101832101833101834101835101836101837101838101839101840101841101842101843101844101845101846101847101848101849101850101851101852101853101854101855101856101857101858101859101860101861101862101863101864101865101866101867101868101869101870101871101872101873101874101875101876101877101878101879101880101881101882101883101884101885101886101887101888101889101890101891101892101893101894101895101896101897101898101899101900101901101902101903101904101905101906101907101908101909101910101911101912101913101914101915101916101917101918101919101920101921101922101923101924101925101926101927101928101929101930101931101932101933101934101935101936101937101938101939101940101941101942101943101944101945101946101947101948101949101950101951101952101953101954101955101956101957101958101959101960101961101962101963101964101965101966101967101968101969101970101971101972101973101974101975101976101977101978101979101980101981101982101983101984101985101986101987101988101989101990101991101992101993101994101995101996101997101998101999102000102001102002102003102004102005102006102007102008102009102010102011102012102013102014102015102016102017102018102019102020102021102022102023102024102025102026102027102028102029102030102031102032102033102034102035102036102037102038102039102040102041102042102043102044102045102046102047102048102049102050102051102052102053102054102055102056102057102058102059102060102061102062102063102064102065102066102067102068102069102070102071102072102073102074102075102076102077102078102079102080102081102082102083102084102085102086102087102088102089102090102091102092102093102094102095102096102097102098102099102100102101102102102103102104102105102106102107102108102109102110102111102112102113102114102115102116102117102118102119102120102121102122102123102124102125102126102127102128102129102130102131102132102133102134102135102136102137102138102139102140102141102142102143102144102145102146102147102148102149102150102151102152102153102154102155102156102157102158102159102160102161102162102163102164102165102166102167102168102169102170102171102172102173102174102175102176102177102178102179102180102181102182102183102184102185102186102187102188102189102190102191102192102193102194102195102196102197102198102199102200102201102202102203102204102205102206102207102208102209102210102211102212102213102214102215102216102217102218102219102220102221102222102223102224102225102226102227102228102229102230102231102232102233102234102235102236102237102238102239102240102241102242102243102244102245102246102247102248102249102250102251102252102253102254102255102256102257102258102259102260102261102262102263102264102265102266102267102268102269102270102271102272102273102274102275102276102277102278102279102280102281102282102283102284102285102286102287102288102289102290102291102292102293102294102295102296102297102298102299102300102301102302102303102304102305102306102307102308102309102310102311102312102313102314102315102316102317102318102319102320102321102322102323102324102325102326102327102328102329102330102331102332102333102334102335102336102337102338102339102340102341102342102343102344102345102346102347102348102349102350102351102352102353102354102355102356102357102358102359102360102361102362102363102364102365102366102367102368102369102370102371102372102373102374102375102376102377102378102379102380102381102382102383102384102385102386102387102388102389102390102391102392102393102394102395102396102397102398102399102400102401102402102403102404102405102406102407102408102409102410102411102412102413102414102415102416102417102418102419102420102421102422102423102424102425102426102427102428102429102430102431102432102433102434102435102436102437102438102439102440102441102442102443102444102445102446102447102448102449102450102451102452102453102454102455102456102457102458102459102460102461102462102463102464102465102466102467102468102469102470102471102472102473102474102475102476102477102478102479102480102481102482102483102484102485102486102487102488102489102490102491102492102493102494102495102496102497102498102499102500102501102502102503102504102505102506102507102508102509102510102511102512102513102514102515102516102517102518102519102520102521102522102523102524102525102526102527102528102529102530102531102532102533102534102535102536102537102538102539102540102541102542102543102544102545102546102547102548102549102550102551102552102553102554102555102556102557102558102559102560102561102562102563102564102565102566102567102568102569102570102571102572102573102574102575102576102577102578102579102580102581102582102583102584102585102586102587102588102589102590102591102592102593102594102595102596102597102598102599102600102601102602102603102604102605102606102607102608102609102610102611102612102613102614102615102616102617102618102619102620102621102622102623102624102625102626102627102628102629102630102631102632102633102634102635102636102637102638102639102640102641102642102643102644102645102646102647102648102649102650102651102652102653102654102655102656102657102658102659102660102661102662102663102664102665102666102667102668102669102670102671102672102673102674102675102676102677102678102679102680102681102682102683102684102685102686102687102688102689102690102691102692102693102694102695102696102697102698102699102700102701102702102703102704102705102706102707102708102709102710102711102712102713102714102715102716102717102718102719102720102721102722102723102724102725102726102727102728102729102730102731102732102733102734102735102736102737102738102739102740102741102742102743102744102745102746102747102748102749102750102751102752102753102754102755102756102757102758102759102760102761102762102763102764102765102766102767102768102769102770102771102772102773102774102775102776102777102778102779102780102781102782102783102784102785102786102787102788102789102790102791102792102793102794102795102796102797102798102799102800102801102802102803102804102805102806102807102808102809102810102811102812102813102814102815102816102817102818102819102820102821102822102823102824102825102826102827102828102829102830102831102832102833102834102835102836102837102838102839102840102841102842102843102844102845102846102847102848102849102850102851102852102853102854102855102856102857102858102859102860102861102862102863102864102865102866102867102868102869102870102871102872102873102874102875102876102877102878102879102880102881102882102883102884102885102886102887102888102889102890102891102892102893102894102895102896102897102898102899102900102901102902102903102904102905102906102907102908102909102910102911102912102913102914102915102916102917102918102919102920102921102922102923102924102925102926102927102928102929102930102931102932102933102934102935102936102937102938102939102940102941102942102943102944102945102946102947102948102949102950102951102952102953102954102955102956102957102958102959102960102961102962102963102964102965102966102967102968102969102970102971102972102973102974102975102976102977102978102979102980102981102982102983102984102985102986102987102988102989102990102991102992102993102994102995102996102997102998102999103000103001103002103003103004103005103006103007103008103009103010103011103012103013103014103015103016103017103018103019103020103021103022103023103024103025103026103027103028103029103030103031103032103033103034103035103036103037103038103039103040103041103042103043103044103045103046103047103048103049103050103051103052103053103054103055103056103057103058103059103060103061103062103063103064103065103066103067103068103069103070103071103072103073103074103075103076103077103078103079103080103081103082103083103084103085103086103087103088103089103090103091103092103093103094103095103096103097103098103099103100103101103102103103103104103105103106103107103108103109103110103111103112103113103114103115103116103117103118103119103120103121103122103123103124103125103126103127103128103129103130103131103132103133103134103135103136103137103138103139103140103141103142103143103144103145103146103147103148103149103150103151103152103153103154103155103156103157103158103159103160103161103162103163103164103165103166103167103168103169103170103171103172103173103174103175103176103177103178103179103180103181103182103183103184103185103186103187103188103189103190103191103192103193103194103195103196103197103198103199103200103201103202103203103204103205103206103207103208103209103210103211103212103213103214103215103216103217103218103219103220103221103222103223103224103225103226103227103228103229103230103231103232103233103234103235103236103237103238103239103240103241103242103243103244103245103246103247103248103249103250103251103252103253103254103255103256103257103258103259103260103261103262103263103264103265103266103267103268103269103270103271103272103273103274103275103276103277103278103279103280103281103282103283103284103285103286103287103288103289103290103291103292103293103294103295103296103297103298103299103300103301103302103303103304103305103306103307103308103309103310103311103312103313103314103315103316103317103318103319103320103321103322103323103324103325103326103327103328103329103330103331103332103333103334103335103336103337103338103339103340103341103342103343103344103345103346103347103348103349103350103351103352103353103354103355103356103357103358103359103360103361103362103363103364103365103366103367103368103369103370103371103372103373103374103375103376103377103378103379103380103381103382103383103384103385103386103387103388103389103390103391103392103393103394103395103396103397103398103399103400103401103402103403103404103405103406103407103408103409103410103411103412103413103414103415103416103417103418103419103420103421103422103423103424103425103426103427103428103429103430103431103432103433103434103435103436103437103438103439103440103441103442103443103444103445103446103447103448103449103450103451103452103453103454103455103456103457103458103459103460103461103462103463103464103465103466103467103468103469103470103471103472103473103474103475103476103477103478103479103480103481103482103483103484103485103486103487103488103489103490103491103492103493103494103495103496103497103498103499103500103501103502103503103504103505103506103507103508103509103510103511103512103513103514103515103516103517103518103519103520103521103522103523103524103525103526103527103528103529103530103531103532103533103534103535103536103537103538103539103540103541103542103543103544103545103546103547103548103549103550103551103552103553103554103555103556103557103558103559103560103561103562103563103564103565103566103567103568103569103570103571103572103573103574103575103576103577103578103579103580103581103582103583103584103585103586103587103588103589103590103591103592103593103594103595103596103597103598103599103600103601103602103603103604103605103606103607103608103609103610103611103612103613103614103615103616103617103618103619103620103621103622103623103624103625103626103627103628103629103630103631103632103633103634103635103636103637103638103639103640103641103642103643103644103645103646103647103648103649103650103651103652103653103654103655103656103657103658103659103660103661103662103663103664103665103666103667103668103669103670103671103672103673103674103675103676103677103678103679103680103681103682103683103684103685103686103687103688103689103690103691103692103693103694103695103696103697103698103699103700103701103702103703103704103705103706103707103708103709103710103711103712103713103714103715103716103717103718103719103720103721103722103723103724103725103726103727103728103729103730103731103732103733103734103735103736103737103738103739103740103741103742103743103744103745103746103747103748103749103750103751103752103753103754103755103756103757103758103759103760103761103762103763103764103765103766103767103768103769103770103771103772103773103774103775103776103777103778103779103780103781103782103783103784103785103786103787103788103789103790103791103792103793103794103795103796103797103798103799103800103801103802103803103804103805103806103807103808103809103810103811103812103813103814103815103816103817103818103819103820103821103822103823103824103825103826103827103828103829103830103831103832103833103834103835103836103837103838103839103840103841103842103843103844103845103846103847103848103849103850103851103852103853103854103855103856103857103858103859103860103861103862103863103864103865103866103867103868103869103870103871103872103873103874103875103876103877103878103879103880103881103882103883103884103885103886103887103888103889103890103891103892103893103894103895103896103897103898103899103900103901103902103903103904103905103906103907103908103909103910103911103912103913103914103915103916103917103918103919103920103921103922103923103924103925103926103927103928103929103930103931103932103933103934103935103936103937103938103939103940103941103942103943103944103945103946103947103948103949103950103951103952103953103954103955103956103957103958103959103960103961103962103963103964103965103966103967103968103969103970103971103972103973103974103975103976103977103978103979103980103981103982103983103984103985103986103987103988103989103990103991103992103993103994103995103996103997103998103999104000104001104002104003104004104005104006104007104008104009104010104011104012104013104014104015104016104017104018104019104020104021104022104023104024104025104026104027104028104029104030104031104032104033104034104035104036104037104038104039104040104041104042104043104044104045104046104047104048104049104050104051104052104053104054104055104056104057104058104059104060104061104062104063104064104065104066104067104068104069104070104071104072104073104074104075104076104077104078104079104080104081104082104083104084104085104086104087104088104089104090104091104092104093104094104095104096104097104098104099104100104101104102104103104104104105104106104107104108104109104110104111104112104113104114104115104116104117104118104119104120104121104122104123104124104125104126104127104128104129104130104131104132104133104134104135104136104137104138104139104140104141104142104143104144104145104146104147104148104149104150104151104152104153104154104155104156104157104158104159104160104161104162104163104164104165104166104167104168104169104170104171104172104173104174104175104176104177104178104179104180104181104182104183104184104185104186104187104188104189104190104191104192104193104194104195104196104197104198104199104200104201104202104203104204104205104206104207104208104209104210104211104212104213104214104215104216104217104218104219104220104221104222104223104224104225104226104227104228104229104230104231104232104233104234104235104236104237104238104239104240104241104242104243104244104245104246104247104248104249104250104251104252104253104254104255104256104257104258104259104260104261104262104263104264104265104266104267104268104269104270104271104272104273104274104275104276104277104278104279104280104281104282104283104284104285104286104287104288104289104290104291104292104293104294104295104296104297104298104299104300104301104302104303104304104305104306104307104308104309104310104311104312104313104314104315104316104317104318104319104320104321104322104323104324104325104326104327104328104329104330104331104332104333104334104335104336104337104338104339104340104341104342104343104344104345104346104347104348104349104350104351104352104353104354104355104356104357104358104359104360104361104362104363104364104365104366104367104368104369104370104371104372104373104374104375104376104377104378104379104380104381104382104383104384104385104386104387104388104389104390104391104392104393104394104395104396104397104398104399104400104401104402104403104404104405104406104407104408104409104410104411104412104413104414104415104416104417104418104419104420104421104422104423104424104425104426104427104428104429104430104431104432104433104434104435104436104437104438104439104440104441104442104443104444104445104446104447104448104449104450104451104452104453104454104455104456104457104458104459104460104461104462104463104464104465104466104467104468104469104470104471104472104473104474104475104476104477104478104479104480104481104482104483104484104485104486104487104488104489104490104491104492104493104494104495104496104497104498104499104500104501104502104503104504104505104506104507104508104509104510104511104512104513104514104515104516104517104518104519104520104521104522104523104524104525104526104527104528104529104530104531104532104533104534104535104536104537104538104539104540104541104542104543104544104545104546104547104548104549104550104551104552104553104554104555104556104557104558104559104560104561104562104563104564104565104566104567104568104569104570104571104572104573104574104575104576104577104578104579104580104581104582104583104584104585104586104587104588104589104590104591104592104593104594104595104596104597104598104599104600104601104602104603104604104605104606104607104608104609104610104611104612104613104614104615104616104617104618104619104620104621104622104623104624104625104626104627104628104629104630104631104632104633104634104635104636104637104638104639104640104641104642104643104644104645104646104647104648104649104650104651104652104653104654104655104656104657104658104659104660104661104662104663104664104665104666104667104668104669104670104671104672104673104674104675104676104677104678104679104680104681104682104683104684104685104686104687104688104689104690104691104692104693104694104695104696104697104698104699104700104701104702104703104704104705104706104707104708104709104710104711104712104713104714104715104716104717104718104719104720104721104722104723104724104725104726104727104728104729104730104731104732104733104734104735104736104737104738104739104740104741104742104743104744104745104746104747104748104749104750104751104752104753104754104755104756104757104758104759104760104761104762104763104764104765104766104767104768104769104770104771104772104773104774104775104776104777104778104779104780104781104782104783104784104785104786104787104788104789104790104791104792104793104794104795104796104797104798104799104800104801104802104803104804104805104806104807104808104809104810104811104812104813104814104815104816104817104818104819104820104821104822104823104824104825104826104827104828104829104830104831104832104833104834104835104836104837104838104839104840104841104842104843104844104845104846104847104848104849104850104851104852104853104854104855104856104857104858104859104860104861104862104863104864104865104866104867104868104869104870104871104872104873104874104875104876104877104878104879104880104881104882104883104884104885104886104887104888104889104890104891104892104893104894104895104896104897104898104899104900104901104902104903104904104905104906104907104908104909104910104911104912104913104914104915104916104917104918104919104920104921104922104923104924104925104926104927104928104929104930104931104932104933104934104935104936104937104938104939104940104941104942104943104944104945104946104947104948104949104950104951104952104953104954104955104956104957104958104959104960104961104962104963104964104965104966104967104968104969104970104971104972104973104974104975104976104977104978104979104980104981104982104983104984104985104986104987104988104989104990104991104992104993104994104995104996104997104998104999105000105001105002105003105004105005105006105007105008105009105010105011105012105013105014105015105016105017105018105019105020105021105022105023105024105025105026105027105028105029105030105031105032105033105034105035105036105037105038105039105040105041105042105043105044105045105046105047105048105049105050105051105052105053105054105055105056105057105058105059105060105061105062105063105064105065105066105067105068105069105070105071105072105073105074105075105076105077105078105079105080105081105082105083105084105085105086105087105088105089105090105091105092105093105094105095105096105097105098105099105100105101105102105103105104105105105106105107105108105109105110105111105112105113105114105115105116105117105118105119105120105121105122105123105124105125105126105127105128105129105130105131105132105133105134105135105136105137105138105139105140105141105142105143105144105145105146105147105148105149105150105151105152105153105154105155105156105157105158105159105160105161105162105163105164105165105166105167105168105169105170105171105172105173105174105175105176105177105178105179105180105181105182105183105184105185105186105187105188105189105190105191105192105193105194105195105196105197105198105199105200105201105202105203105204105205105206105207105208105209105210105211105212105213105214105215105216105217105218105219105220105221105222105223105224105225105226105227105228105229105230105231105232105233105234105235105236105237105238105239105240105241105242105243105244105245105246105247105248105249105250105251105252105253105254105255105256105257105258105259105260105261105262105263105264105265105266105267105268105269105270105271105272105273105274105275105276105277105278105279105280105281105282105283105284105285105286105287105288105289105290105291105292105293105294105295105296105297105298105299105300105301105302105303105304105305105306105307105308105309105310105311105312105313105314105315105316105317105318105319105320105321105322105323105324105325105326105327105328105329105330105331105332105333105334105335105336105337105338105339105340105341105342105343105344105345105346105347105348105349105350105351105352105353105354105355105356105357105358105359105360105361105362105363105364105365105366105367105368105369105370105371105372105373105374105375105376105377105378105379105380105381105382105383105384105385105386105387105388105389105390105391105392105393105394105395105396105397105398105399105400105401105402105403105404105405105406105407105408105409105410105411105412105413105414105415105416105417105418105419105420105421105422105423105424105425105426105427105428105429105430105431105432105433105434105435105436105437105438105439105440105441105442105443105444105445105446105447105448105449105450105451105452105453105454105455105456105457105458105459105460105461105462105463105464105465105466105467105468105469105470105471105472105473105474105475105476105477105478105479105480105481105482105483105484105485105486105487105488105489105490105491105492105493105494105495105496105497105498105499105500105501105502105503105504105505105506105507105508105509105510105511105512105513105514105515105516105517105518105519105520105521105522105523105524105525105526105527105528105529105530105531105532105533105534105535105536105537105538105539105540105541105542105543105544105545105546105547105548105549105550105551105552105553105554105555105556105557105558105559105560105561105562105563105564105565105566105567105568105569105570105571105572105573105574105575105576105577105578105579105580105581105582105583105584105585105586105587105588105589105590105591105592105593105594105595105596105597105598105599105600105601105602105603105604105605105606105607105608105609105610105611105612105613105614105615105616105617105618105619105620105621105622105623105624105625105626105627105628105629105630105631105632105633105634105635105636105637105638105639105640105641105642105643105644105645105646105647105648105649105650105651105652105653105654105655105656105657105658105659105660105661105662105663105664105665105666105667105668105669105670105671105672105673105674105675105676105677105678105679105680105681105682105683105684105685105686105687105688105689105690105691105692105693105694105695105696105697105698105699105700105701105702105703105704105705105706105707105708105709105710105711105712105713105714105715105716105717105718105719105720105721105722105723105724105725105726105727105728105729105730105731105732105733105734105735105736105737105738105739105740105741105742105743105744105745105746105747105748105749105750105751105752105753105754105755105756105757105758105759105760105761105762105763105764105765105766105767105768105769105770105771105772105773105774105775105776105777105778105779105780105781105782105783105784105785105786105787105788105789105790105791105792105793105794105795105796105797105798105799105800105801105802105803105804105805105806105807105808105809105810105811105812105813105814105815105816105817105818105819105820105821105822105823105824105825105826105827105828105829105830105831105832105833105834105835105836105837105838105839105840105841105842105843105844105845105846105847105848105849105850105851105852105853105854105855105856105857105858105859105860105861105862105863105864105865105866105867105868105869105870105871105872105873105874105875105876105877105878105879105880105881105882105883105884105885105886105887105888105889105890105891105892105893105894105895105896105897105898105899105900105901105902105903105904105905105906105907105908105909105910105911105912105913105914105915105916105917105918105919105920105921105922105923105924105925105926105927105928105929105930105931105932105933105934105935105936105937105938105939105940105941105942105943105944105945105946105947105948105949105950105951105952105953105954105955105956105957105958105959105960105961105962105963105964105965105966105967105968105969105970105971105972105973105974105975105976105977105978105979105980105981105982105983105984105985105986105987105988105989105990105991105992105993105994105995105996105997105998105999106000106001106002106003106004106005106006106007106008106009106010106011106012106013106014106015106016106017106018106019106020106021106022106023106024106025106026106027106028106029106030106031106032106033106034106035106036106037106038106039106040106041106042106043106044106045106046106047106048106049106050106051106052106053106054106055106056106057106058106059106060106061106062106063106064106065106066106067106068106069106070106071106072106073106074106075106076106077106078106079106080106081106082106083106084106085106086106087106088106089106090106091106092106093106094106095106096106097106098106099106100106101106102106103106104106105106106106107106108106109106110106111106112106113106114106115106116106117106118106119106120106121106122106123106124106125106126106127106128106129106130106131106132106133106134106135106136106137106138106139106140106141106142106143106144106145106146106147106148106149106150106151106152106153106154106155106156106157106158106159106160106161106162106163106164106165106166106167106168106169106170106171106172106173106174106175106176106177106178106179106180106181106182106183106184106185106186106187106188106189106190106191106192106193106194106195106196106197106198106199106200106201106202106203106204106205106206106207106208106209106210106211106212106213106214106215106216106217106218106219106220106221106222106223106224106225106226106227106228106229106230106231106232106233106234106235106236106237106238106239106240106241106242106243106244106245106246106247106248106249106250106251106252106253106254106255106256106257106258106259106260106261106262106263106264106265106266106267106268106269106270106271106272106273106274106275106276106277106278106279106280106281106282106283106284106285106286106287106288106289106290106291106292106293106294106295106296106297106298106299106300106301106302106303106304106305106306106307106308106309106310106311106312106313106314106315106316106317106318106319106320106321106322106323106324106325106326106327106328106329106330106331106332106333106334106335106336106337106338106339106340106341106342106343106344106345106346106347106348106349106350106351106352106353106354106355106356106357106358106359106360106361106362106363106364106365106366106367106368106369106370106371106372106373106374106375106376106377106378106379106380106381106382106383106384106385106386106387106388106389106390106391106392106393106394106395106396106397106398106399106400106401106402106403106404106405106406106407106408106409106410106411106412106413106414106415106416106417106418106419106420106421106422106423106424106425106426106427106428106429106430106431106432106433106434106435106436106437106438106439106440106441106442106443106444106445106446106447106448106449106450106451106452106453106454106455106456106457106458106459106460106461106462106463106464106465106466106467106468106469106470106471106472106473106474106475106476106477106478106479106480106481106482106483106484106485106486106487106488106489106490106491106492106493106494106495106496106497106498106499106500106501106502106503106504106505106506106507106508106509106510106511106512106513106514106515106516106517106518106519106520106521106522106523106524106525106526106527106528106529106530106531106532106533106534106535106536106537106538106539106540106541106542106543106544106545106546106547106548106549106550106551106552106553106554106555106556106557106558106559106560106561106562106563106564106565106566106567106568106569106570106571106572106573106574106575106576106577106578106579106580106581106582106583106584106585106586106587106588106589106590106591106592106593106594106595106596106597106598106599106600106601106602106603106604106605106606106607106608106609106610106611106612106613106614106615106616106617106618106619106620106621106622106623106624106625106626106627106628106629106630106631106632106633106634106635106636106637106638106639106640106641106642106643106644106645106646106647106648106649106650106651106652106653106654106655106656106657106658106659106660106661106662106663106664106665106666106667106668106669106670106671106672106673106674106675106676106677106678106679106680106681106682106683106684106685106686106687106688106689106690106691106692106693106694106695106696106697106698106699106700106701106702106703106704106705106706106707106708106709106710106711106712106713106714106715106716106717106718106719106720106721106722106723106724106725106726106727106728106729106730106731106732106733106734106735106736106737106738106739106740106741106742106743106744106745106746106747106748106749106750106751106752106753106754106755106756106757106758106759106760106761106762106763106764106765106766106767106768106769106770106771106772106773106774106775106776106777106778106779106780106781106782106783106784106785106786106787106788106789106790106791106792106793106794106795106796106797106798106799106800106801106802106803106804106805106806106807106808106809106810106811106812106813106814106815106816106817106818106819106820106821106822106823106824106825106826106827106828106829106830106831106832106833106834106835106836106837106838106839106840106841106842106843106844106845106846106847106848106849106850106851106852106853106854106855106856106857106858106859106860106861106862106863106864106865106866106867106868106869106870106871106872106873106874106875106876106877106878106879106880106881106882106883106884106885106886106887106888106889106890106891106892106893106894106895106896106897106898106899106900106901106902106903106904106905106906106907106908106909106910106911106912106913106914106915106916106917106918106919106920106921106922106923106924106925106926106927106928106929106930106931106932106933106934106935106936106937106938106939106940106941106942106943106944106945106946106947106948106949106950106951106952106953106954106955106956106957106958106959106960106961106962106963106964106965106966106967106968106969106970106971106972106973106974106975106976106977106978106979106980106981106982106983106984106985106986106987106988106989106990106991106992106993106994106995106996106997106998106999107000107001107002107003107004107005107006107007107008107009107010107011107012107013107014107015107016107017107018107019107020107021107022107023107024107025107026107027107028107029107030107031107032107033107034107035107036107037107038107039107040107041107042107043107044107045107046107047107048107049107050107051107052107053107054107055107056107057107058107059107060107061107062107063107064107065107066107067107068107069107070107071107072107073107074107075107076107077107078107079107080107081107082107083107084107085107086107087107088107089107090107091107092107093107094107095107096107097107098107099107100107101107102107103107104107105107106107107107108107109107110107111107112107113107114107115107116107117107118107119107120107121107122107123107124107125107126107127107128107129107130107131107132107133107134107135107136107137107138107139107140107141107142107143107144107145107146107147107148107149107150107151107152107153107154107155107156107157107158107159107160107161107162107163107164107165107166107167107168107169107170107171107172107173107174107175107176107177107178107179107180107181107182107183107184107185107186107187107188107189107190107191107192107193107194107195107196107197107198107199107200107201107202107203107204107205107206107207107208107209107210107211107212107213107214107215107216107217107218107219107220107221107222107223107224107225107226107227107228107229107230107231107232107233107234107235107236107237107238107239107240107241107242107243107244107245107246107247107248107249107250107251107252107253107254107255107256107257107258107259107260107261107262107263107264107265107266107267107268107269107270107271107272107273107274107275107276107277107278107279107280107281107282107283107284107285107286107287107288107289107290107291107292107293107294107295107296107297107298107299107300107301107302107303107304107305107306107307107308107309107310107311107312107313107314107315107316107317107318107319107320107321107322107323107324107325107326107327107328107329107330107331107332107333107334107335107336107337107338107339107340107341107342107343107344107345107346107347107348107349107350107351107352107353107354107355107356107357107358107359107360107361107362107363107364107365107366107367107368107369107370107371107372107373107374107375107376107377107378107379107380107381107382107383107384107385107386107387107388107389107390107391107392107393107394107395107396107397107398107399107400107401107402107403107404107405107406107407107408107409107410107411107412107413107414107415107416107417107418107419107420107421107422107423107424107425107426107427107428107429107430107431107432107433107434107435107436107437107438107439107440107441107442107443107444107445107446107447107448107449107450107451107452107453107454107455107456107457107458107459107460107461107462107463107464107465107466107467107468107469107470107471107472107473107474107475107476107477107478107479107480107481107482107483107484107485107486107487107488107489107490107491107492107493107494107495107496107497107498107499107500107501107502107503107504107505107506107507107508107509107510107511107512107513107514107515107516107517107518107519107520107521107522107523107524107525107526107527107528107529107530107531107532107533107534107535107536107537107538107539107540107541107542107543107544107545107546107547107548107549107550107551107552107553107554107555107556107557107558107559107560107561107562107563107564107565107566107567107568107569107570107571107572107573107574107575107576107577107578107579107580107581107582107583107584107585107586107587107588107589107590107591107592107593107594107595107596107597107598107599107600107601107602107603107604107605107606107607107608107609107610107611107612107613107614107615107616107617107618107619107620107621107622107623107624107625107626107627107628107629107630107631107632107633107634107635107636107637107638107639107640107641107642107643107644107645107646107647107648107649107650107651107652107653107654107655107656107657107658107659107660107661107662107663107664107665107666107667107668107669107670107671107672107673107674107675107676107677107678107679107680107681107682107683107684107685107686107687107688107689107690107691107692107693107694107695107696107697107698107699107700107701107702107703107704107705107706107707107708107709107710107711107712107713107714107715107716107717107718107719107720107721107722107723107724107725107726107727107728107729107730107731107732107733107734107735107736107737107738107739107740107741107742107743107744107745107746107747107748107749107750107751107752107753107754107755107756107757107758107759107760107761107762107763107764107765107766107767107768107769107770107771107772107773107774107775107776107777107778107779107780107781107782107783107784107785107786107787107788107789107790107791107792107793107794107795107796107797107798107799107800107801107802107803107804107805107806107807107808107809107810107811107812107813107814107815107816107817107818107819107820107821107822107823107824107825107826107827107828107829107830107831107832107833107834107835107836107837107838107839107840107841107842107843107844107845107846107847107848107849107850107851107852107853107854107855107856107857107858107859107860107861107862107863107864107865107866107867107868107869107870107871107872107873107874107875107876107877107878107879107880107881107882107883107884107885107886107887107888107889107890107891107892107893107894107895107896107897107898107899107900107901107902107903107904107905107906107907107908107909107910107911107912107913107914107915107916107917107918107919107920107921107922107923107924107925107926107927107928107929107930107931107932107933107934107935107936107937107938107939107940107941107942107943107944107945107946107947107948107949107950107951107952107953107954107955107956107957107958107959107960107961107962107963107964107965107966107967107968107969107970107971107972107973107974107975107976107977107978107979107980107981107982107983107984107985107986107987107988107989107990107991107992107993107994107995107996107997107998107999108000108001108002108003108004108005108006108007108008108009108010108011108012108013108014108015108016108017108018108019108020108021108022108023108024108025108026108027108028108029108030108031108032108033108034108035108036108037108038108039108040108041108042108043108044108045108046108047108048108049108050108051108052108053108054108055108056108057108058108059108060108061108062108063108064108065108066108067108068108069108070108071108072108073108074108075108076108077108078108079108080108081108082108083108084108085108086108087108088108089108090108091108092108093108094108095108096108097108098108099108100108101108102108103108104108105108106108107108108108109108110108111108112108113108114108115108116108117108118108119108120108121108122108123108124108125108126108127108128108129108130108131108132108133108134108135108136108137108138108139108140108141108142108143108144108145108146108147108148108149108150108151108152108153108154108155108156108157108158108159108160108161108162108163108164108165108166108167108168108169108170108171108172108173108174108175108176108177108178108179108180108181108182108183108184108185108186108187108188108189108190108191108192108193108194108195108196108197108198108199108200108201108202108203108204108205108206108207108208108209108210108211108212108213108214108215108216108217108218108219108220108221108222108223108224108225108226108227108228108229108230108231108232108233108234108235108236108237108238108239108240108241108242108243108244108245108246108247108248108249108250108251108252108253108254108255108256108257108258108259108260108261108262108263108264108265108266108267108268108269108270108271108272108273108274108275108276108277108278108279108280108281108282108283108284108285108286108287108288108289108290108291108292108293108294108295108296108297108298108299108300108301108302108303108304108305108306108307108308108309108310108311108312108313108314108315108316108317108318108319108320108321108322108323108324108325108326108327108328108329108330108331108332108333108334108335108336108337108338108339108340108341108342108343108344108345108346108347108348108349108350108351108352108353108354108355108356108357108358108359108360108361108362108363108364108365108366108367108368108369108370108371108372108373108374108375108376108377108378108379108380108381108382108383108384108385108386108387108388108389108390108391108392108393108394108395108396108397108398108399108400108401108402108403108404108405108406108407108408108409108410108411108412108413108414108415108416108417108418108419108420108421108422108423108424108425108426108427108428108429108430108431108432108433108434108435108436108437108438108439108440108441108442108443108444108445108446108447108448108449108450108451108452108453108454108455108456108457108458108459108460108461108462108463108464108465108466108467108468108469108470108471108472108473108474108475108476108477108478108479108480108481108482108483108484108485108486108487108488108489108490108491108492108493108494108495108496108497108498108499108500108501108502108503108504108505108506108507108508108509108510108511108512108513108514108515108516108517108518108519108520108521108522108523108524108525108526108527108528108529108530108531108532108533108534108535108536108537108538108539108540108541108542108543108544108545108546108547108548108549108550108551108552108553108554108555108556108557108558108559108560108561108562108563108564108565108566108567108568108569108570108571108572108573108574
  1. #!/usr/bin/env php
  2. <?php
  3. if (!version_compare(PHP_VERSION, PHP_VERSION, '=')) {
  4. fwrite(
  5. STDERR,
  6. sprintf(
  7. '%s declares an invalid value for PHP_VERSION.' . PHP_EOL .
  8. 'This breaks fundamental functionality such as version_compare().' . PHP_EOL .
  9. 'Please use a different PHP interpreter.' . PHP_EOL,
  10. PHP_BINARY
  11. )
  12. );
  13. die(1);
  14. }
  15. if (version_compare('8.1.0', PHP_VERSION, '>')) {
  16. fwrite(
  17. STDERR,
  18. sprintf(
  19. 'PHPUnit 10.5.40 by Sebastian Bergmann and contributors.' . PHP_EOL . PHP_EOL .
  20. 'This version of PHPUnit requires PHP >= 8.1.' . PHP_EOL .
  21. 'You are using PHP %s (%s).' . PHP_EOL,
  22. PHP_VERSION,
  23. PHP_BINARY
  24. )
  25. );
  26. die(1);
  27. }
  28. $requiredExtensions = ['ctype', 'dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter'];
  29. $unavailableExtensions = array_filter(
  30. $requiredExtensions,
  31. static function ($extension) {
  32. return !extension_loaded($extension);
  33. }
  34. );
  35. if ([] !== $unavailableExtensions) {
  36. fwrite(
  37. STDERR,
  38. sprintf(
  39. 'PHPUnit requires the "%s" extensions, but the "%s" %s not available.' . PHP_EOL,
  40. implode('", "', $requiredExtensions),
  41. implode('", "', $unavailableExtensions),
  42. count($unavailableExtensions) === 1 ? 'extension is' : 'extensions are'
  43. )
  44. );
  45. die(1);
  46. }
  47. unset($requiredExtensions, $unavailableExtensions);
  48. if (__FILE__ === realpath($_SERVER['SCRIPT_NAME'])) {
  49. $execute = true;
  50. } else {
  51. $execute = false;
  52. }
  53. $options = getopt('', array('composer-lock', 'manifest', 'sbom'));
  54. if (isset($options['composer-lock'])) {
  55. $printComposerLock = true;
  56. } elseif (isset($options['manifest'])) {
  57. $printManifest = true;
  58. } elseif (isset($options['sbom'])) {
  59. $printSbom = true;
  60. }
  61. unset($options);
  62. define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', __FILE__));
  63. define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-10.5.40.phar');
  64. Phar::mapPhar('phpunit-10.5.40.phar');
  65. spl_autoload_register(
  66. function ($class) {
  67. static $classes = null;
  68. if ($classes === null) {
  69. $classes = ['PHPUnitPHAR\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy.php',
  70. 'PHPUnitPHAR\\DeepCopy\\Exception\\CloneException' => '/myclabs-deep-copy/DeepCopy/Exception/CloneException.php',
  71. 'PHPUnitPHAR\\DeepCopy\\Exception\\PropertyException' => '/myclabs-deep-copy/DeepCopy/Exception/PropertyException.php',
  72. 'PHPUnitPHAR\\DeepCopy\\Filter\\ChainableFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.php',
  73. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php',
  74. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php',
  75. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php',
  76. 'PHPUnitPHAR\\DeepCopy\\Filter\\Filter' => '/myclabs-deep-copy/DeepCopy/Filter/Filter.php',
  77. 'PHPUnitPHAR\\DeepCopy\\Filter\\KeepFilter' => '/myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php',
  78. 'PHPUnitPHAR\\DeepCopy\\Filter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php',
  79. 'PHPUnitPHAR\\DeepCopy\\Filter\\SetNullFilter' => '/myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php',
  80. 'PHPUnitPHAR\\DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php',
  81. 'PHPUnitPHAR\\DeepCopy\\Matcher\\Matcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Matcher.php',
  82. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php',
  83. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyNameMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php',
  84. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyTypeMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php',
  85. 'PHPUnitPHAR\\DeepCopy\\Reflection\\ReflectionHelper' => '/myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php',
  86. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php',
  87. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DatePeriodFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php',
  88. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php',
  89. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ShallowCopyFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php',
  90. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\ArrayObjectFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php',
  91. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php',
  92. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php',
  93. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\TypeFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php',
  94. 'PHPUnitPHAR\\DeepCopy\\TypeMatcher\\TypeMatcher' => '/myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php',
  95. 'PHPUnitPHAR\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php',
  96. 'PHPUnitPHAR\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php',
  97. 'PHPUnitPHAR\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php',
  98. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollection' => '/phar-io-manifest/values/AuthorCollection.php',
  99. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollectionIterator' => '/phar-io-manifest/values/AuthorCollectionIterator.php',
  100. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElement' => '/phar-io-manifest/xml/AuthorElement.php',
  101. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElementCollection' => '/phar-io-manifest/xml/AuthorElementCollection.php',
  102. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponent' => '/phar-io-manifest/values/BundledComponent.php',
  103. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollection' => '/phar-io-manifest/values/BundledComponentCollection.php',
  104. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollectionIterator' => '/phar-io-manifest/values/BundledComponentCollectionIterator.php',
  105. 'PHPUnitPHAR\\PharIo\\Manifest\\BundlesElement' => '/phar-io-manifest/xml/BundlesElement.php',
  106. 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElement' => '/phar-io-manifest/xml/ComponentElement.php',
  107. 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElementCollection' => '/phar-io-manifest/xml/ComponentElementCollection.php',
  108. 'PHPUnitPHAR\\PharIo\\Manifest\\ContainsElement' => '/phar-io-manifest/xml/ContainsElement.php',
  109. 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightElement' => '/phar-io-manifest/xml/CopyrightElement.php',
  110. 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightInformation' => '/phar-io-manifest/values/CopyrightInformation.php',
  111. 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollection' => '/phar-io-manifest/xml/ElementCollection.php',
  112. 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollectionException' => '/phar-io-manifest/exceptions/ElementCollectionException.php',
  113. 'PHPUnitPHAR\\PharIo\\Manifest\\Email' => '/phar-io-manifest/values/Email.php',
  114. 'PHPUnitPHAR\\PharIo\\Manifest\\Exception' => '/phar-io-manifest/exceptions/Exception.php',
  115. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElement' => '/phar-io-manifest/xml/ExtElement.php',
  116. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElementCollection' => '/phar-io-manifest/xml/ExtElementCollection.php',
  117. 'PHPUnitPHAR\\PharIo\\Manifest\\Extension' => '/phar-io-manifest/values/Extension.php',
  118. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtensionElement' => '/phar-io-manifest/xml/ExtensionElement.php',
  119. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidApplicationNameException' => '/phar-io-manifest/exceptions/InvalidApplicationNameException.php',
  120. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidEmailException' => '/phar-io-manifest/exceptions/InvalidEmailException.php',
  121. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidUrlException' => '/phar-io-manifest/exceptions/InvalidUrlException.php',
  122. 'PHPUnitPHAR\\PharIo\\Manifest\\Library' => '/phar-io-manifest/values/Library.php',
  123. 'PHPUnitPHAR\\PharIo\\Manifest\\License' => '/phar-io-manifest/values/License.php',
  124. 'PHPUnitPHAR\\PharIo\\Manifest\\LicenseElement' => '/phar-io-manifest/xml/LicenseElement.php',
  125. 'PHPUnitPHAR\\PharIo\\Manifest\\Manifest' => '/phar-io-manifest/values/Manifest.php',
  126. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocument' => '/phar-io-manifest/xml/ManifestDocument.php',
  127. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentException' => '/phar-io-manifest/exceptions/ManifestDocumentException.php',
  128. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentLoadingException' => '/phar-io-manifest/exceptions/ManifestDocumentLoadingException.php',
  129. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapper' => '/phar-io-manifest/ManifestDocumentMapper.php',
  130. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapperException' => '/phar-io-manifest/exceptions/ManifestDocumentMapperException.php',
  131. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElement' => '/phar-io-manifest/xml/ManifestElement.php',
  132. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElementException' => '/phar-io-manifest/exceptions/ManifestElementException.php',
  133. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoader' => '/phar-io-manifest/ManifestLoader.php',
  134. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoaderException' => '/phar-io-manifest/exceptions/ManifestLoaderException.php',
  135. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestSerializer' => '/phar-io-manifest/ManifestSerializer.php',
  136. 'PHPUnitPHAR\\PharIo\\Manifest\\NoEmailAddressException' => '/phar-io-manifest/exceptions/NoEmailAddressException.php',
  137. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpElement' => '/phar-io-manifest/xml/PhpElement.php',
  138. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpExtensionRequirement' => '/phar-io-manifest/values/PhpExtensionRequirement.php',
  139. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpVersionRequirement' => '/phar-io-manifest/values/PhpVersionRequirement.php',
  140. 'PHPUnitPHAR\\PharIo\\Manifest\\Requirement' => '/phar-io-manifest/values/Requirement.php',
  141. 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollection' => '/phar-io-manifest/values/RequirementCollection.php',
  142. 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollectionIterator' => '/phar-io-manifest/values/RequirementCollectionIterator.php',
  143. 'PHPUnitPHAR\\PharIo\\Manifest\\RequiresElement' => '/phar-io-manifest/xml/RequiresElement.php',
  144. 'PHPUnitPHAR\\PharIo\\Manifest\\Type' => '/phar-io-manifest/values/Type.php',
  145. 'PHPUnitPHAR\\PharIo\\Manifest\\Url' => '/phar-io-manifest/values/Url.php',
  146. 'PHPUnitPHAR\\PharIo\\Version\\AbstractVersionConstraint' => '/phar-io-version/constraints/AbstractVersionConstraint.php',
  147. 'PHPUnitPHAR\\PharIo\\Version\\AndVersionConstraintGroup' => '/phar-io-version/constraints/AndVersionConstraintGroup.php',
  148. 'PHPUnitPHAR\\PharIo\\Version\\AnyVersionConstraint' => '/phar-io-version/constraints/AnyVersionConstraint.php',
  149. 'PHPUnitPHAR\\PharIo\\Version\\BuildMetaData' => '/phar-io-version/BuildMetaData.php',
  150. 'PHPUnitPHAR\\PharIo\\Version\\ExactVersionConstraint' => '/phar-io-version/constraints/ExactVersionConstraint.php',
  151. 'PHPUnitPHAR\\PharIo\\Version\\Exception' => '/phar-io-version/exceptions/Exception.php',
  152. 'PHPUnitPHAR\\PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => '/phar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php',
  153. 'PHPUnitPHAR\\PharIo\\Version\\InvalidPreReleaseSuffixException' => '/phar-io-version/exceptions/InvalidPreReleaseSuffixException.php',
  154. 'PHPUnitPHAR\\PharIo\\Version\\InvalidVersionException' => '/phar-io-version/exceptions/InvalidVersionException.php',
  155. 'PHPUnitPHAR\\PharIo\\Version\\NoBuildMetaDataException' => '/phar-io-version/exceptions/NoBuildMetaDataException.php',
  156. 'PHPUnitPHAR\\PharIo\\Version\\NoPreReleaseSuffixException' => '/phar-io-version/exceptions/NoPreReleaseSuffixException.php',
  157. 'PHPUnitPHAR\\PharIo\\Version\\OrVersionConstraintGroup' => '/phar-io-version/constraints/OrVersionConstraintGroup.php',
  158. 'PHPUnitPHAR\\PharIo\\Version\\PreReleaseSuffix' => '/phar-io-version/PreReleaseSuffix.php',
  159. 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.php',
  160. 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorVersionConstraint.php',
  161. 'PHPUnitPHAR\\PharIo\\Version\\UnsupportedVersionConstraintException' => '/phar-io-version/exceptions/UnsupportedVersionConstraintException.php',
  162. 'PHPUnitPHAR\\PharIo\\Version\\Version' => '/phar-io-version/Version.php',
  163. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraint' => '/phar-io-version/constraints/VersionConstraint.php',
  164. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintParser' => '/phar-io-version/VersionConstraintParser.php',
  165. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintValue' => '/phar-io-version/VersionConstraintValue.php',
  166. 'PHPUnitPHAR\\PharIo\\Version\\VersionNumber' => '/phar-io-version/VersionNumber.php',
  167. 'PHPUnitPHAR\\PhpParser\\Builder' => '/nikic-php-parser/PhpParser/Builder.php',
  168. 'PHPUnitPHAR\\PhpParser\\BuilderFactory' => '/nikic-php-parser/PhpParser/BuilderFactory.php',
  169. 'PHPUnitPHAR\\PhpParser\\BuilderHelpers' => '/nikic-php-parser/PhpParser/BuilderHelpers.php',
  170. 'PHPUnitPHAR\\PhpParser\\Builder\\ClassConst' => '/nikic-php-parser/PhpParser/Builder/ClassConst.php',
  171. 'PHPUnitPHAR\\PhpParser\\Builder\\Class_' => '/nikic-php-parser/PhpParser/Builder/Class_.php',
  172. 'PHPUnitPHAR\\PhpParser\\Builder\\Declaration' => '/nikic-php-parser/PhpParser/Builder/Declaration.php',
  173. 'PHPUnitPHAR\\PhpParser\\Builder\\EnumCase' => '/nikic-php-parser/PhpParser/Builder/EnumCase.php',
  174. 'PHPUnitPHAR\\PhpParser\\Builder\\Enum_' => '/nikic-php-parser/PhpParser/Builder/Enum_.php',
  175. 'PHPUnitPHAR\\PhpParser\\Builder\\FunctionLike' => '/nikic-php-parser/PhpParser/Builder/FunctionLike.php',
  176. 'PHPUnitPHAR\\PhpParser\\Builder\\Function_' => '/nikic-php-parser/PhpParser/Builder/Function_.php',
  177. 'PHPUnitPHAR\\PhpParser\\Builder\\Interface_' => '/nikic-php-parser/PhpParser/Builder/Interface_.php',
  178. 'PHPUnitPHAR\\PhpParser\\Builder\\Method' => '/nikic-php-parser/PhpParser/Builder/Method.php',
  179. 'PHPUnitPHAR\\PhpParser\\Builder\\Namespace_' => '/nikic-php-parser/PhpParser/Builder/Namespace_.php',
  180. 'PHPUnitPHAR\\PhpParser\\Builder\\Param' => '/nikic-php-parser/PhpParser/Builder/Param.php',
  181. 'PHPUnitPHAR\\PhpParser\\Builder\\Property' => '/nikic-php-parser/PhpParser/Builder/Property.php',
  182. 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUse' => '/nikic-php-parser/PhpParser/Builder/TraitUse.php',
  183. 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.php',
  184. 'PHPUnitPHAR\\PhpParser\\Builder\\Trait_' => '/nikic-php-parser/PhpParser/Builder/Trait_.php',
  185. 'PHPUnitPHAR\\PhpParser\\Builder\\Use_' => '/nikic-php-parser/PhpParser/Builder/Use_.php',
  186. 'PHPUnitPHAR\\PhpParser\\Comment' => '/nikic-php-parser/PhpParser/Comment.php',
  187. 'PHPUnitPHAR\\PhpParser\\Comment\\Doc' => '/nikic-php-parser/PhpParser/Comment/Doc.php',
  188. 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluationException' => '/nikic-php-parser/PhpParser/ConstExprEvaluationException.php',
  189. 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluator' => '/nikic-php-parser/PhpParser/ConstExprEvaluator.php',
  190. 'PHPUnitPHAR\\PhpParser\\Error' => '/nikic-php-parser/PhpParser/Error.php',
  191. 'PHPUnitPHAR\\PhpParser\\ErrorHandler' => '/nikic-php-parser/PhpParser/ErrorHandler.php',
  192. 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Collecting' => '/nikic-php-parser/PhpParser/ErrorHandler/Collecting.php',
  193. 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Throwing' => '/nikic-php-parser/PhpParser/ErrorHandler/Throwing.php',
  194. 'PHPUnitPHAR\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php',
  195. 'PHPUnitPHAR\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php',
  196. 'PHPUnitPHAR\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php',
  197. 'PHPUnitPHAR\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php',
  198. 'PHPUnitPHAR\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php',
  199. 'PHPUnitPHAR\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php',
  200. 'PHPUnitPHAR\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php',
  201. 'PHPUnitPHAR\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php',
  202. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AsymmetricVisibilityTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php',
  203. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
  204. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
  205. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
  206. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
  207. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
  208. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
  209. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PropertyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php',
  210. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
  211. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
  212. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
  213. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
  214. 'PHPUnitPHAR\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php',
  215. 'PHPUnitPHAR\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php',
  216. 'PHPUnitPHAR\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php',
  217. 'PHPUnitPHAR\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php',
  218. 'PHPUnitPHAR\\PhpParser\\NodeDumper' => '/nikic-php-parser/PhpParser/NodeDumper.php',
  219. 'PHPUnitPHAR\\PhpParser\\NodeFinder' => '/nikic-php-parser/PhpParser/NodeFinder.php',
  220. 'PHPUnitPHAR\\PhpParser\\NodeTraverser' => '/nikic-php-parser/PhpParser/NodeTraverser.php',
  221. 'PHPUnitPHAR\\PhpParser\\NodeTraverserInterface' => '/nikic-php-parser/PhpParser/NodeTraverserInterface.php',
  222. 'PHPUnitPHAR\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php',
  223. 'PHPUnitPHAR\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php',
  224. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php',
  225. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php',
  226. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php',
  227. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php',
  228. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php',
  229. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
  230. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
  231. 'PHPUnitPHAR\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php',
  232. 'PHPUnitPHAR\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php',
  233. 'PHPUnitPHAR\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php',
  234. 'PHPUnitPHAR\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php',
  235. 'PHPUnitPHAR\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php',
  236. 'PHPUnitPHAR\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php',
  237. 'PHPUnitPHAR\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php',
  238. 'PHPUnitPHAR\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php',
  239. 'PHPUnitPHAR\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php',
  240. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php',
  241. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php',
  242. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php',
  243. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php',
  244. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp.php',
  245. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
  246. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
  247. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
  248. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php',
  249. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.php',
  250. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.php',
  251. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.php',
  252. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.php',
  253. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.php',
  254. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.php',
  255. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.php',
  256. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
  257. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
  258. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignRef' => '/nikic-php-parser/PhpParser/Node/Expr/AssignRef.php',
  259. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp.php',
  260. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
  261. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
  262. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
  263. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
  264. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
  265. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
  266. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.php',
  267. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.php',
  268. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.php',
  269. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.php',
  270. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
  271. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.php',
  272. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
  273. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
  274. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
  275. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.php',
  276. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.php',
  277. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.php',
  278. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
  279. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
  280. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.php',
  281. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.php',
  282. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
  283. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
  284. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.php',
  285. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
  286. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
  287. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BitwiseNot' => '/nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php',
  288. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BooleanNot' => '/nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php',
  289. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\CallLike' => '/nikic-php-parser/PhpParser/Node/Expr/CallLike.php',
  290. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast' => '/nikic-php-parser/PhpParser/Node/Expr/Cast.php',
  291. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.php',
  292. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Bool_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.php',
  293. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Double' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php',
  294. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Int_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.php',
  295. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Object_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.php',
  296. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\String_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/String_.php',
  297. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Unset_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.php',
  298. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php',
  299. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php',
  300. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php',
  301. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php',
  302. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php',
  303. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php',
  304. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ErrorSuppress' => '/nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php',
  305. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Eval_' => '/nikic-php-parser/PhpParser/Node/Expr/Eval_.php',
  306. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Exit_' => '/nikic-php-parser/PhpParser/Node/Expr/Exit_.php',
  307. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\FuncCall' => '/nikic-php-parser/PhpParser/Node/Expr/FuncCall.php',
  308. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Include_' => '/nikic-php-parser/PhpParser/Node/Expr/Include_.php',
  309. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Instanceof_' => '/nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php',
  310. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Isset_' => '/nikic-php-parser/PhpParser/Node/Expr/Isset_.php',
  311. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\List_' => '/nikic-php-parser/PhpParser/Node/Expr/List_.php',
  312. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Match_' => '/nikic-php-parser/PhpParser/Node/Expr/Match_.php',
  313. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\MethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/MethodCall.php',
  314. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\New_' => '/nikic-php-parser/PhpParser/Node/Expr/New_.php',
  315. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.php',
  316. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php',
  317. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostDec' => '/nikic-php-parser/PhpParser/Node/Expr/PostDec.php',
  318. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostInc' => '/nikic-php-parser/PhpParser/Node/Expr/PostInc.php',
  319. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreDec' => '/nikic-php-parser/PhpParser/Node/Expr/PreDec.php',
  320. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreInc' => '/nikic-php-parser/PhpParser/Node/Expr/PreInc.php',
  321. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Print_' => '/nikic-php-parser/PhpParser/Node/Expr/Print_.php',
  322. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.php',
  323. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ShellExec' => '/nikic-php-parser/PhpParser/Node/Expr/ShellExec.php',
  324. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticCall' => '/nikic-php-parser/PhpParser/Node/Expr/StaticCall.php',
  325. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php',
  326. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Ternary' => '/nikic-php-parser/PhpParser/Node/Expr/Ternary.php',
  327. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Throw_' => '/nikic-php-parser/PhpParser/Node/Expr/Throw_.php',
  328. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryMinus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php',
  329. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryPlus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.php',
  330. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Variable' => '/nikic-php-parser/PhpParser/Node/Expr/Variable.php',
  331. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\YieldFrom' => '/nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php',
  332. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php',
  333. 'PHPUnitPHAR\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php',
  334. 'PHPUnitPHAR\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php',
  335. 'PHPUnitPHAR\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php',
  336. 'PHPUnitPHAR\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php',
  337. 'PHPUnitPHAR\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php',
  338. 'PHPUnitPHAR\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php',
  339. 'PHPUnitPHAR\\PhpParser\\Node\\Name\\FullyQualified' => '/nikic-php-parser/PhpParser/Node/Name/FullyQualified.php',
  340. 'PHPUnitPHAR\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php',
  341. 'PHPUnitPHAR\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php',
  342. 'PHPUnitPHAR\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php',
  343. 'PHPUnitPHAR\\PhpParser\\Node\\PropertyHook' => '/nikic-php-parser/PhpParser/Node/PropertyHook.php',
  344. 'PHPUnitPHAR\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php',
  345. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php',
  346. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php',
  347. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php',
  348. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php',
  349. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php',
  350. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php',
  351. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php',
  352. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\File' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.php',
  353. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php',
  354. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.php',
  355. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php',
  356. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
  357. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Property' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.php',
  358. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php',
  359. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php',
  360. 'PHPUnitPHAR\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php',
  361. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php',
  362. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php',
  363. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php',
  364. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php',
  365. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php',
  366. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassConst' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassConst.php',
  367. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassLike' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php',
  368. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassMethod' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php',
  369. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php',
  370. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php',
  371. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php',
  372. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php',
  373. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php',
  374. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php',
  375. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ElseIf_' => '/nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php',
  376. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Else_' => '/nikic-php-parser/PhpParser/Node/Stmt/Else_.php',
  377. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\EnumCase' => '/nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php',
  378. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Enum_' => '/nikic-php-parser/PhpParser/Node/Stmt/Enum_.php',
  379. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Expression' => '/nikic-php-parser/PhpParser/Node/Stmt/Expression.php',
  380. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Finally_' => '/nikic-php-parser/PhpParser/Node/Stmt/Finally_.php',
  381. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\For_' => '/nikic-php-parser/PhpParser/Node/Stmt/For_.php',
  382. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Foreach_' => '/nikic-php-parser/PhpParser/Node/Stmt/Foreach_.php',
  383. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Function_' => '/nikic-php-parser/PhpParser/Node/Stmt/Function_.php',
  384. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Global_' => '/nikic-php-parser/PhpParser/Node/Stmt/Global_.php',
  385. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Goto_' => '/nikic-php-parser/PhpParser/Node/Stmt/Goto_.php',
  386. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\GroupUse' => '/nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php',
  387. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\HaltCompiler' => '/nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php',
  388. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\If_' => '/nikic-php-parser/PhpParser/Node/Stmt/If_.php',
  389. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\InlineHTML' => '/nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php',
  390. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Interface_' => '/nikic-php-parser/PhpParser/Node/Stmt/Interface_.php',
  391. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Label' => '/nikic-php-parser/PhpParser/Node/Stmt/Label.php',
  392. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php',
  393. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php',
  394. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php',
  395. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php',
  396. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php',
  397. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php',
  398. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php',
  399. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php',
  400. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
  401. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
  402. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php',
  403. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php',
  404. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php',
  405. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php',
  406. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php',
  407. 'PHPUnitPHAR\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php',
  408. 'PHPUnitPHAR\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php',
  409. 'PHPUnitPHAR\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php',
  410. 'PHPUnitPHAR\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php',
  411. 'PHPUnitPHAR\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php',
  412. 'PHPUnitPHAR\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php',
  413. 'PHPUnitPHAR\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php',
  414. 'PHPUnitPHAR\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php',
  415. 'PHPUnitPHAR\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php',
  416. 'PHPUnitPHAR\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php',
  417. 'PHPUnitPHAR\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php',
  418. 'PHPUnitPHAR\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php',
  419. 'PHPUnitPHAR\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php',
  420. 'PHPUnitPHAR\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php',
  421. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\AmbiguousOptionException' => '/sebastian-cli-parser/exceptions/AmbiguousOptionException.php',
  422. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Exception' => '/sebastian-cli-parser/exceptions/Exception.php',
  423. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\OptionDoesNotAllowArgumentException' => '/sebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.php',
  424. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Parser' => '/sebastian-cli-parser/Parser.php',
  425. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\RequiredOptionArgumentMissingException' => '/sebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.php',
  426. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\UnknownOptionException' => '/sebastian-cli-parser/exceptions/UnknownOptionException.php',
  427. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\BranchAndPathCoverageNotSupportedException' => '/php-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.php',
  428. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\CodeCoverage' => '/php-code-coverage/CodeCoverage.php',
  429. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\ProcessedCodeCoverageData' => '/php-code-coverage/Data/ProcessedCodeCoverageData.php',
  430. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\RawCodeCoverageData' => '/php-code-coverage/Data/RawCodeCoverageData.php',
  431. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\DeadCodeDetectionNotSupportedException' => '/php-code-coverage/Exception/DeadCodeDetectionNotSupportedException.php',
  432. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Driver' => '/php-code-coverage/Driver/Driver.php',
  433. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PathExistsButIsNotDirectoryException' => '/php-code-coverage/Exception/PathExistsButIsNotDirectoryException.php',
  434. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovDriver' => '/php-code-coverage/Driver/PcovDriver.php',
  435. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovNotAvailableException' => '/php-code-coverage/Exception/PcovNotAvailableException.php',
  436. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Selector' => '/php-code-coverage/Driver/Selector.php',
  437. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\WriteOperationFailedException' => '/php-code-coverage/Exception/WriteOperationFailedException.php',
  438. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugDriver' => '/php-code-coverage/Driver/XdebugDriver.php',
  439. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php',
  440. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php',
  441. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php',
  442. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php',
  443. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php',
  444. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php',
  445. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php',
  446. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverWithPathCoverageSupportAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.php',
  447. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => '/php-code-coverage/Node/AbstractNode.php',
  448. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Builder' => '/php-code-coverage/Node/Builder.php',
  449. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\CrapIndex' => '/php-code-coverage/Node/CrapIndex.php',
  450. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Directory' => '/php-code-coverage/Node/Directory.php',
  451. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\File' => '/php-code-coverage/Node/File.php',
  452. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Iterator' => '/php-code-coverage/Node/Iterator.php',
  453. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ParserException' => '/php-code-coverage/Exception/ParserException.php',
  454. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReflectionException' => '/php-code-coverage/Exception/ReflectionException.php',
  455. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReportAlreadyFinalizedException' => '/php-code-coverage/Exception/ReportAlreadyFinalizedException.php',
  456. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Clover' => '/php-code-coverage/Report/Clover.php',
  457. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Cobertura' => '/php-code-coverage/Report/Cobertura.php',
  458. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => '/php-code-coverage/Report/Crap4j.php',
  459. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Colors' => '/php-code-coverage/Report/Html/Colors.php',
  460. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\CustomCssFile' => '/php-code-coverage/Report/Html/CustomCssFile.php',
  461. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => '/php-code-coverage/Report/Html/Renderer/Dashboard.php',
  462. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => '/php-code-coverage/Report/Html/Renderer/Directory.php',
  463. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => '/php-code-coverage/Report/Html/Facade.php',
  464. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => '/php-code-coverage/Report/Html/Renderer/File.php',
  465. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => '/php-code-coverage/Report/Html/Renderer.php',
  466. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\PHP' => '/php-code-coverage/Report/PHP.php',
  467. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Text' => '/php-code-coverage/Report/Text.php',
  468. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Thresholds' => '/php-code-coverage/Report/Thresholds.php',
  469. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => '/php-code-coverage/Report/Xml/BuildInformation.php',
  470. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => '/php-code-coverage/Report/Xml/Coverage.php',
  471. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => '/php-code-coverage/Report/Xml/Directory.php',
  472. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => '/php-code-coverage/Report/Xml/Facade.php',
  473. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => '/php-code-coverage/Report/Xml/File.php',
  474. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => '/php-code-coverage/Report/Xml/Method.php',
  475. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => '/php-code-coverage/Report/Xml/Node.php',
  476. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => '/php-code-coverage/Report/Xml/Project.php',
  477. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => '/php-code-coverage/Report/Xml/Report.php',
  478. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => '/php-code-coverage/Report/Xml/Source.php',
  479. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => '/php-code-coverage/Report/Xml/Tests.php',
  480. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => '/php-code-coverage/Report/Xml/Totals.php',
  481. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => '/php-code-coverage/Report/Xml/Unit.php',
  482. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysisCacheNotConfiguredException' => '/php-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.php',
  483. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CacheWarmer' => '/php-code-coverage/StaticAnalysis/CacheWarmer.php',
  484. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CachingFileAnalyser' => '/php-code-coverage/StaticAnalysis/CachingFileAnalyser.php',
  485. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CodeUnitFindingVisitor' => '/php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php',
  486. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ExecutableLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php',
  487. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\FileAnalyser' => '/php-code-coverage/StaticAnalysis/FileAnalyser.php',
  488. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\IgnoredLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php',
  489. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParsingFileAnalyser' => '/php-code-coverage/StaticAnalysis/ParsingFileAnalyser.php',
  490. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\TestIdMissingException' => '/php-code-coverage/Exception/TestIdMissingException.php',
  491. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Known' => '/php-code-coverage/TestSize/Known.php',
  492. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Large' => '/php-code-coverage/TestSize/Large.php',
  493. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Medium' => '/php-code-coverage/TestSize/Medium.php',
  494. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Small' => '/php-code-coverage/TestSize/Small.php',
  495. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\TestSize' => '/php-code-coverage/TestSize/TestSize.php',
  496. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Unknown' => '/php-code-coverage/TestSize/Unknown.php',
  497. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Failure' => '/php-code-coverage/TestStatus/Failure.php',
  498. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Known' => '/php-code-coverage/TestStatus/Known.php',
  499. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Success' => '/php-code-coverage/TestStatus/Success.php',
  500. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\TestStatus' => '/php-code-coverage/TestStatus/TestStatus.php',
  501. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Unknown' => '/php-code-coverage/TestStatus/Unknown.php',
  502. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => '/php-code-coverage/Exception/UnintentionallyCoveredCodeException.php',
  503. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\DirectoryCouldNotBeCreatedException' => '/php-code-coverage/Exception/DirectoryCouldNotBeCreatedException.php',
  504. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Filesystem' => '/php-code-coverage/Util/Filesystem.php',
  505. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Percentage' => '/php-code-coverage/Util/Percentage.php',
  506. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Version' => '/php-code-coverage/Version.php',
  507. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\XmlException' => '/php-code-coverage/Exception/XmlException.php',
  508. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => '/sebastian-code-unit-reverse-lookup/Wizard.php',
  509. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassMethodUnit' => '/sebastian-code-unit/ClassMethodUnit.php',
  510. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassUnit' => '/sebastian-code-unit/ClassUnit.php',
  511. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnit' => '/sebastian-code-unit/CodeUnit.php',
  512. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollection' => '/sebastian-code-unit/CodeUnitCollection.php',
  513. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollectionIterator' => '/sebastian-code-unit/CodeUnitCollectionIterator.php',
  514. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Exception' => '/sebastian-code-unit/exceptions/Exception.php',
  515. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FileUnit' => '/sebastian-code-unit/FileUnit.php',
  516. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FunctionUnit' => '/sebastian-code-unit/FunctionUnit.php',
  517. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceMethodUnit' => '/sebastian-code-unit/InterfaceMethodUnit.php',
  518. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceUnit' => '/sebastian-code-unit/InterfaceUnit.php',
  519. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InvalidCodeUnitException' => '/sebastian-code-unit/exceptions/InvalidCodeUnitException.php',
  520. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Mapper' => '/sebastian-code-unit/Mapper.php',
  521. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\NoTraitException' => '/sebastian-code-unit/exceptions/NoTraitException.php',
  522. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ReflectionException' => '/sebastian-code-unit/exceptions/ReflectionException.php',
  523. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitMethodUnit' => '/sebastian-code-unit/TraitMethodUnit.php',
  524. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitUnit' => '/sebastian-code-unit/TraitUnit.php',
  525. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ArrayComparator' => '/sebastian-comparator/ArrayComparator.php',
  526. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Comparator' => '/sebastian-comparator/Comparator.php',
  527. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ComparisonFailure' => '/sebastian-comparator/ComparisonFailure.php',
  528. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DOMNodeComparator' => '/sebastian-comparator/DOMNodeComparator.php',
  529. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DateTimeComparator' => '/sebastian-comparator/DateTimeComparator.php',
  530. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Exception' => '/sebastian-comparator/exceptions/Exception.php',
  531. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ExceptionComparator' => '/sebastian-comparator/ExceptionComparator.php',
  532. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Factory' => '/sebastian-comparator/Factory.php',
  533. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\MockObjectComparator' => '/sebastian-comparator/MockObjectComparator.php',
  534. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\NumericComparator' => '/sebastian-comparator/NumericComparator.php',
  535. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ObjectComparator' => '/sebastian-comparator/ObjectComparator.php',
  536. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ResourceComparator' => '/sebastian-comparator/ResourceComparator.php',
  537. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\RuntimeException' => '/sebastian-comparator/exceptions/RuntimeException.php',
  538. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ScalarComparator' => '/sebastian-comparator/ScalarComparator.php',
  539. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\SplObjectStorageComparator' => '/sebastian-comparator/SplObjectStorageComparator.php',
  540. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\TypeComparator' => '/sebastian-comparator/TypeComparator.php',
  541. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Calculator' => '/sebastian-complexity/Calculator.php',
  542. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Complexity' => '/sebastian-complexity/Complexity/Complexity.php',
  543. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php',
  544. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollection' => '/sebastian-complexity/Complexity/ComplexityCollection.php',
  545. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollectionIterator' => '/sebastian-complexity/Complexity/ComplexityCollectionIterator.php',
  546. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\CyclomaticComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php',
  547. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Exception' => '/sebastian-complexity/Exception/Exception.php',
  548. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\RuntimeException' => '/sebastian-complexity/Exception/RuntimeException.php',
  549. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Chunk' => '/sebastian-diff/Chunk.php',
  550. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\ConfigurationException' => '/sebastian-diff/Exception/ConfigurationException.php',
  551. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Diff' => '/sebastian-diff/Diff.php',
  552. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Differ' => '/sebastian-diff/Differ.php',
  553. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Exception' => '/sebastian-diff/Exception/Exception.php',
  554. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\InvalidArgumentException' => '/sebastian-diff/Exception/InvalidArgumentException.php',
  555. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Line' => '/sebastian-diff/Line.php',
  556. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => '/sebastian-diff/LongestCommonSubsequenceCalculator.php',
  557. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.php',
  558. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => '/sebastian-diff/Output/AbstractChunkOutputBuilder.php',
  559. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => '/sebastian-diff/Output/DiffOnlyOutputBuilder.php',
  560. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => '/sebastian-diff/Output/DiffOutputBuilderInterface.php',
  561. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => '/sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php',
  562. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => '/sebastian-diff/Output/UnifiedDiffOutputBuilder.php',
  563. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Parser' => '/sebastian-diff/Parser.php',
  564. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php',
  565. 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Console' => '/sebastian-environment/Console.php',
  566. 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Runtime' => '/sebastian-environment/Runtime.php',
  567. 'PHPUnitPHAR\\SebastianBergmann\\Exporter\\Exporter' => '/sebastian-exporter/Exporter.php',
  568. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\ExcludeIterator' => '/php-file-iterator/ExcludeIterator.php',
  569. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Facade' => '/php-file-iterator/Facade.php',
  570. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Factory' => '/php-file-iterator/Factory.php',
  571. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Iterator' => '/php-file-iterator/Iterator.php',
  572. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\CodeExporter' => '/sebastian-global-state/CodeExporter.php',
  573. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Exception' => '/sebastian-global-state/exceptions/Exception.php',
  574. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\ExcludeList' => '/sebastian-global-state/ExcludeList.php',
  575. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Restorer' => '/sebastian-global-state/Restorer.php',
  576. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\RuntimeException' => '/sebastian-global-state/exceptions/RuntimeException.php',
  577. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Snapshot' => '/sebastian-global-state/Snapshot.php',
  578. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Exception' => '/php-invoker/exceptions/Exception.php',
  579. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Invoker' => '/php-invoker/Invoker.php',
  580. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\ProcessControlExtensionNotLoadedException' => '/php-invoker/exceptions/ProcessControlExtensionNotLoadedException.php',
  581. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\TimeoutException' => '/php-invoker/exceptions/TimeoutException.php',
  582. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Counter' => '/sebastian-lines-of-code/Counter.php',
  583. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Exception' => '/sebastian-lines-of-code/Exception/Exception.php',
  584. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\IllogicalValuesException' => '/sebastian-lines-of-code/Exception/IllogicalValuesException.php',
  585. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LineCountingVisitor' => '/sebastian-lines-of-code/LineCountingVisitor.php',
  586. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LinesOfCode' => '/sebastian-lines-of-code/LinesOfCode.php',
  587. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\NegativeValueException' => '/sebastian-lines-of-code/Exception/NegativeValueException.php',
  588. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\RuntimeException' => '/sebastian-lines-of-code/Exception/RuntimeException.php',
  589. 'PHPUnitPHAR\\SebastianBergmann\\ObjectEnumerator\\Enumerator' => '/sebastian-object-enumerator/Enumerator.php',
  590. 'PHPUnitPHAR\\SebastianBergmann\\ObjectReflector\\ObjectReflector' => '/sebastian-object-reflector/ObjectReflector.php',
  591. 'PHPUnitPHAR\\SebastianBergmann\\RecursionContext\\Context' => '/sebastian-recursion-context/Context.php',
  592. 'PHPUnitPHAR\\SebastianBergmann\\Template\\Exception' => '/php-text-template/exceptions/Exception.php',
  593. 'PHPUnitPHAR\\SebastianBergmann\\Template\\InvalidArgumentException' => '/php-text-template/exceptions/InvalidArgumentException.php',
  594. 'PHPUnitPHAR\\SebastianBergmann\\Template\\RuntimeException' => '/php-text-template/exceptions/RuntimeException.php',
  595. 'PHPUnitPHAR\\SebastianBergmann\\Template\\Template' => '/php-text-template/Template.php',
  596. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Duration' => '/php-timer/Duration.php',
  597. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Exception' => '/php-timer/exceptions/Exception.php',
  598. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\NoActiveTimerException' => '/php-timer/exceptions/NoActiveTimerException.php',
  599. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\ResourceUsageFormatter' => '/php-timer/ResourceUsageFormatter.php',
  600. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\TimeSinceStartOfRequestNotAvailableException' => '/php-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.php',
  601. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Timer' => '/php-timer/Timer.php',
  602. 'PHPUnitPHAR\\SebastianBergmann\\Type\\CallableType' => '/sebastian-type/type/CallableType.php',
  603. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Exception' => '/sebastian-type/exception/Exception.php',
  604. 'PHPUnitPHAR\\SebastianBergmann\\Type\\FalseType' => '/sebastian-type/type/FalseType.php',
  605. 'PHPUnitPHAR\\SebastianBergmann\\Type\\GenericObjectType' => '/sebastian-type/type/GenericObjectType.php',
  606. 'PHPUnitPHAR\\SebastianBergmann\\Type\\IntersectionType' => '/sebastian-type/type/IntersectionType.php',
  607. 'PHPUnitPHAR\\SebastianBergmann\\Type\\IterableType' => '/sebastian-type/type/IterableType.php',
  608. 'PHPUnitPHAR\\SebastianBergmann\\Type\\MixedType' => '/sebastian-type/type/MixedType.php',
  609. 'PHPUnitPHAR\\SebastianBergmann\\Type\\NeverType' => '/sebastian-type/type/NeverType.php',
  610. 'PHPUnitPHAR\\SebastianBergmann\\Type\\NullType' => '/sebastian-type/type/NullType.php',
  611. 'PHPUnitPHAR\\SebastianBergmann\\Type\\ObjectType' => '/sebastian-type/type/ObjectType.php',
  612. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Parameter' => '/sebastian-type/Parameter.php',
  613. 'PHPUnitPHAR\\SebastianBergmann\\Type\\ReflectionMapper' => '/sebastian-type/ReflectionMapper.php',
  614. 'PHPUnitPHAR\\SebastianBergmann\\Type\\RuntimeException' => '/sebastian-type/exception/RuntimeException.php',
  615. 'PHPUnitPHAR\\SebastianBergmann\\Type\\SimpleType' => '/sebastian-type/type/SimpleType.php',
  616. 'PHPUnitPHAR\\SebastianBergmann\\Type\\StaticType' => '/sebastian-type/type/StaticType.php',
  617. 'PHPUnitPHAR\\SebastianBergmann\\Type\\TrueType' => '/sebastian-type/type/TrueType.php',
  618. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Type' => '/sebastian-type/type/Type.php',
  619. 'PHPUnitPHAR\\SebastianBergmann\\Type\\TypeName' => '/sebastian-type/TypeName.php',
  620. 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnionType' => '/sebastian-type/type/UnionType.php',
  621. 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnknownType' => '/sebastian-type/type/UnknownType.php',
  622. 'PHPUnitPHAR\\SebastianBergmann\\Type\\VoidType' => '/sebastian-type/type/VoidType.php',
  623. 'PHPUnitPHAR\\SebastianBergmann\\Version' => '/sebastian-version/Version.php',
  624. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php',
  625. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php',
  626. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php',
  627. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Token' => '/theseer-tokenizer/Token.php',
  628. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollection' => '/theseer-tokenizer/TokenCollection.php',
  629. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollectionException' => '/theseer-tokenizer/TokenCollectionException.php',
  630. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Tokenizer' => '/theseer-tokenizer/Tokenizer.php',
  631. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php',
  632. 'PHPUnit\\Event\\Application\\Finished' => '/phpunit/Event/Events/Application/Finished.php',
  633. 'PHPUnit\\Event\\Application\\FinishedSubscriber' => '/phpunit/Event/Events/Application/FinishedSubscriber.php',
  634. 'PHPUnit\\Event\\Application\\Started' => '/phpunit/Event/Events/Application/Started.php',
  635. 'PHPUnit\\Event\\Application\\StartedSubscriber' => '/phpunit/Event/Events/Application/StartedSubscriber.php',
  636. 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php',
  637. 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php',
  638. 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php',
  639. 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php',
  640. 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php',
  641. 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php',
  642. 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php',
  643. 'PHPUnit\\Event\\Code\\TestCollectionIterator' => '/phpunit/Event/Value/Test/TestCollectionIterator.php',
  644. 'PHPUnit\\Event\\Code\\TestDox' => '/phpunit/Event/Value/Test/TestDox.php',
  645. 'PHPUnit\\Event\\Code\\TestDoxBuilder' => '/phpunit/Event/Value/Test/TestDoxBuilder.php',
  646. 'PHPUnit\\Event\\Code\\TestMethod' => '/phpunit/Event/Value/Test/TestMethod.php',
  647. 'PHPUnit\\Event\\Code\\TestMethodBuilder' => '/phpunit/Event/Value/Test/TestMethodBuilder.php',
  648. 'PHPUnit\\Event\\Code\\Throwable' => '/phpunit/Event/Value/Throwable.php',
  649. 'PHPUnit\\Event\\Code\\ThrowableBuilder' => '/phpunit/Event/Value/ThrowableBuilder.php',
  650. 'PHPUnit\\Event\\CollectingDispatcher' => '/phpunit/Event/Dispatcher/CollectingDispatcher.php',
  651. 'PHPUnit\\Event\\DeferringDispatcher' => '/phpunit/Event/Dispatcher/DeferringDispatcher.php',
  652. 'PHPUnit\\Event\\DirectDispatcher' => '/phpunit/Event/Dispatcher/DirectDispatcher.php',
  653. 'PHPUnit\\Event\\Dispatcher' => '/phpunit/Event/Dispatcher/Dispatcher.php',
  654. 'PHPUnit\\Event\\DispatchingEmitter' => '/phpunit/Event/Emitter/DispatchingEmitter.php',
  655. 'PHPUnit\\Event\\Emitter' => '/phpunit/Event/Emitter/Emitter.php',
  656. 'PHPUnit\\Event\\Event' => '/phpunit/Event/Events/Event.php',
  657. 'PHPUnit\\Event\\EventAlreadyAssignedException' => '/phpunit/Event/Exception/EventAlreadyAssignedException.php',
  658. 'PHPUnit\\Event\\EventCollection' => '/phpunit/Event/Events/EventCollection.php',
  659. 'PHPUnit\\Event\\EventCollectionIterator' => '/phpunit/Event/Events/EventCollectionIterator.php',
  660. 'PHPUnit\\Event\\EventFacadeIsSealedException' => '/phpunit/Event/Exception/EventFacadeIsSealedException.php',
  661. 'PHPUnit\\Event\\Exception' => '/phpunit/Event/Exception/Exception.php',
  662. 'PHPUnit\\Event\\Facade' => '/phpunit/Event/Facade.php',
  663. 'PHPUnit\\Event\\InvalidArgumentException' => '/phpunit/Event/Exception/InvalidArgumentException.php',
  664. 'PHPUnit\\Event\\InvalidEventException' => '/phpunit/Event/Exception/InvalidEventException.php',
  665. 'PHPUnit\\Event\\InvalidSubscriberException' => '/phpunit/Event/Exception/InvalidSubscriberException.php',
  666. 'PHPUnit\\Event\\MapError' => '/phpunit/Event/Exception/MapError.php',
  667. 'PHPUnit\\Event\\NoPreviousThrowableException' => '/phpunit/Event/Exception/NoPreviousThrowableException.php',
  668. 'PHPUnit\\Event\\RuntimeException' => '/phpunit/Event/Exception/RuntimeException.php',
  669. 'PHPUnit\\Event\\Runtime\\OperatingSystem' => '/phpunit/Event/Value/Runtime/OperatingSystem.php',
  670. 'PHPUnit\\Event\\Runtime\\PHP' => '/phpunit/Event/Value/Runtime/PHP.php',
  671. 'PHPUnit\\Event\\Runtime\\PHPUnit' => '/phpunit/Event/Value/Runtime/PHPUnit.php',
  672. 'PHPUnit\\Event\\Runtime\\Runtime' => '/phpunit/Event/Value/Runtime/Runtime.php',
  673. 'PHPUnit\\Event\\SubscribableDispatcher' => '/phpunit/Event/Dispatcher/SubscribableDispatcher.php',
  674. 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php',
  675. 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php',
  676. 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php',
  677. 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php',
  678. 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php',
  679. 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php',
  680. 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php',
  681. 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php',
  682. 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php',
  683. 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php',
  684. 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php',
  685. 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php',
  686. 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php',
  687. 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php',
  688. 'PHPUnit\\Event\\Telemetry\\SystemMemoryMeter' => '/phpunit/Event/Value/Telemetry/SystemMemoryMeter.php',
  689. 'PHPUnit\\Event\\Telemetry\\SystemStopWatch' => '/phpunit/Event/Value/Telemetry/SystemStopWatch.php',
  690. 'PHPUnit\\Event\\Telemetry\\SystemStopWatchWithOffset' => '/phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php',
  691. 'PHPUnit\\Event\\TestData\\DataFromDataProvider' => '/phpunit/Event/Value/Test/TestData/DataFromDataProvider.php',
  692. 'PHPUnit\\Event\\TestData\\DataFromTestDependency' => '/phpunit/Event/Value/Test/TestData/DataFromTestDependency.php',
  693. 'PHPUnit\\Event\\TestData\\MoreThanOneDataSetFromDataProviderException' => '/phpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php',
  694. 'PHPUnit\\Event\\TestData\\NoDataSetFromDataProviderException' => '/phpunit/Event/Exception/NoDataSetFromDataProviderException.php',
  695. 'PHPUnit\\Event\\TestData\\TestData' => '/phpunit/Event/Value/Test/TestData/TestData.php',
  696. 'PHPUnit\\Event\\TestData\\TestDataCollection' => '/phpunit/Event/Value/Test/TestData/TestDataCollection.php',
  697. 'PHPUnit\\Event\\TestData\\TestDataCollectionIterator' => '/phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.php',
  698. 'PHPUnit\\Event\\TestRunner\\BootstrapFinished' => '/phpunit/Event/Events/TestRunner/BootstrapFinished.php',
  699. 'PHPUnit\\Event\\TestRunner\\BootstrapFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.php',
  700. 'PHPUnit\\Event\\TestRunner\\Configured' => '/phpunit/Event/Events/TestRunner/Configured.php',
  701. 'PHPUnit\\Event\\TestRunner\\ConfiguredSubscriber' => '/phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php',
  702. 'PHPUnit\\Event\\TestRunner\\DeprecationTriggered' => '/phpunit/Event/Events/TestRunner/DeprecationTriggered.php',
  703. 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php',
  704. 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php',
  705. 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php',
  706. 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php',
  707. 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php',
  708. 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php',
  709. 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php',
  710. 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php',
  711. 'PHPUnit\\Event\\TestRunner\\ExecutionStartedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.php',
  712. 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrapped' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrapped.php',
  713. 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrappedSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.php',
  714. 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPhar' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.php',
  715. 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php',
  716. 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php',
  717. 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php',
  718. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php',
  719. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php',
  720. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php',
  721. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php',
  722. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php',
  723. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php',
  724. 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php',
  725. 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php',
  726. 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php',
  727. 'PHPUnit\\Event\\TestRunner\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.php',
  728. 'PHPUnit\\Event\\TestSuite\\Filtered' => '/phpunit/Event/Events/TestSuite/Filtered.php',
  729. 'PHPUnit\\Event\\TestSuite\\FilteredSubscriber' => '/phpunit/Event/Events/TestSuite/FilteredSubscriber.php',
  730. 'PHPUnit\\Event\\TestSuite\\Finished' => '/phpunit/Event/Events/TestSuite/Finished.php',
  731. 'PHPUnit\\Event\\TestSuite\\FinishedSubscriber' => '/phpunit/Event/Events/TestSuite/FinishedSubscriber.php',
  732. 'PHPUnit\\Event\\TestSuite\\Loaded' => '/phpunit/Event/Events/TestSuite/Loaded.php',
  733. 'PHPUnit\\Event\\TestSuite\\LoadedSubscriber' => '/phpunit/Event/Events/TestSuite/LoadedSubscriber.php',
  734. 'PHPUnit\\Event\\TestSuite\\Skipped' => '/phpunit/Event/Events/TestSuite/Skipped.php',
  735. 'PHPUnit\\Event\\TestSuite\\SkippedSubscriber' => '/phpunit/Event/Events/TestSuite/SkippedSubscriber.php',
  736. 'PHPUnit\\Event\\TestSuite\\Sorted' => '/phpunit/Event/Events/TestSuite/Sorted.php',
  737. 'PHPUnit\\Event\\TestSuite\\SortedSubscriber' => '/phpunit/Event/Events/TestSuite/SortedSubscriber.php',
  738. 'PHPUnit\\Event\\TestSuite\\Started' => '/phpunit/Event/Events/TestSuite/Started.php',
  739. 'PHPUnit\\Event\\TestSuite\\StartedSubscriber' => '/phpunit/Event/Events/TestSuite/StartedSubscriber.php',
  740. 'PHPUnit\\Event\\TestSuite\\TestSuite' => '/phpunit/Event/Value/TestSuite/TestSuite.php',
  741. 'PHPUnit\\Event\\TestSuite\\TestSuiteBuilder' => '/phpunit/Event/Value/TestSuite/TestSuiteBuilder.php',
  742. 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestClass' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php',
  743. 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestMethodWithDataProvider' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.php',
  744. 'PHPUnit\\Event\\TestSuite\\TestSuiteWithName' => '/phpunit/Event/Value/TestSuite/TestSuiteWithName.php',
  745. 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.php',
  746. 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.php',
  747. 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php',
  748. 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.php',
  749. 'PHPUnit\\Event\\Test\\AfterTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php',
  750. 'PHPUnit\\Event\\Test\\AfterTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.php',
  751. 'PHPUnit\\Event\\Test\\AfterTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php',
  752. 'PHPUnit\\Event\\Test\\AfterTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.php',
  753. 'PHPUnit\\Event\\Test\\AssertionFailed' => '/phpunit/Event/Events/Test/Assertion/AssertionFailed.php',
  754. 'PHPUnit\\Event\\Test\\AssertionFailedSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.php',
  755. 'PHPUnit\\Event\\Test\\AssertionSucceeded' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php',
  756. 'PHPUnit\\Event\\Test\\AssertionSucceededSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.php',
  757. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.php',
  758. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.php',
  759. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.php',
  760. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.php',
  761. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.php',
  762. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.php',
  763. 'PHPUnit\\Event\\Test\\BeforeTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.php',
  764. 'PHPUnit\\Event\\Test\\BeforeTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.php',
  765. 'PHPUnit\\Event\\Test\\BeforeTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.php',
  766. 'PHPUnit\\Event\\Test\\BeforeTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.php',
  767. 'PHPUnit\\Event\\Test\\ComparatorRegistered' => '/phpunit/Event/Events/Test/ComparatorRegistered.php',
  768. 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php',
  769. 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php',
  770. 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php',
  771. 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php',
  772. 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php',
  773. 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php',
  774. 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php',
  775. 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php',
  776. 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php',
  777. 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php',
  778. 'PHPUnit\\Event\\Test\\ErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php',
  779. 'PHPUnit\\Event\\Test\\Errored' => '/phpunit/Event/Events/Test/Outcome/Errored.php',
  780. 'PHPUnit\\Event\\Test\\ErroredSubscriber' => '/phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php',
  781. 'PHPUnit\\Event\\Test\\Failed' => '/phpunit/Event/Events/Test/Outcome/Failed.php',
  782. 'PHPUnit\\Event\\Test\\FailedSubscriber' => '/phpunit/Event/Events/Test/Outcome/FailedSubscriber.php',
  783. 'PHPUnit\\Event\\Test\\Finished' => '/phpunit/Event/Events/Test/Lifecycle/Finished.php',
  784. 'PHPUnit\\Event\\Test\\FinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php',
  785. 'PHPUnit\\Event\\Test\\MarkedIncomplete' => '/phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php',
  786. 'PHPUnit\\Event\\Test\\MarkedIncompleteSubscriber' => '/phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php',
  787. 'PHPUnit\\Event\\Test\\MockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php',
  788. 'PHPUnit\\Event\\Test\\MockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php',
  789. 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php',
  790. 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php',
  791. 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.php',
  792. 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.php',
  793. 'PHPUnit\\Event\\Test\\MockObjectForTraitCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php',
  794. 'PHPUnit\\Event\\Test\\MockObjectForTraitCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.php',
  795. 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php',
  796. 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.php',
  797. 'PHPUnit\\Event\\Test\\NoComparisonFailureException' => '/phpunit/Event/Exception/NoComparisonFailureException.php',
  798. 'PHPUnit\\Event\\Test\\NoticeTriggered' => '/phpunit/Event/Events/Test/Issue/NoticeTriggered.php',
  799. 'PHPUnit\\Event\\Test\\NoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php',
  800. 'PHPUnit\\Event\\Test\\PartialMockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php',
  801. 'PHPUnit\\Event\\Test\\PartialMockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.php',
  802. 'PHPUnit\\Event\\Test\\Passed' => '/phpunit/Event/Events/Test/Outcome/Passed.php',
  803. 'PHPUnit\\Event\\Test\\PassedSubscriber' => '/phpunit/Event/Events/Test/Outcome/PassedSubscriber.php',
  804. 'PHPUnit\\Event\\Test\\PhpDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php',
  805. 'PHPUnit\\Event\\Test\\PhpDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.php',
  806. 'PHPUnit\\Event\\Test\\PhpNoticeTriggered' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php',
  807. 'PHPUnit\\Event\\Test\\PhpNoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php',
  808. 'PHPUnit\\Event\\Test\\PhpWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php',
  809. 'PHPUnit\\Event\\Test\\PhpWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php',
  810. 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.php',
  811. 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.php',
  812. 'PHPUnit\\Event\\Test\\PhpunitErrorTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.php',
  813. 'PHPUnit\\Event\\Test\\PhpunitErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.php',
  814. 'PHPUnit\\Event\\Test\\PhpunitWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php',
  815. 'PHPUnit\\Event\\Test\\PhpunitWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.php',
  816. 'PHPUnit\\Event\\Test\\PostConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalled.php',
  817. 'PHPUnit\\Event\\Test\\PostConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php',
  818. 'PHPUnit\\Event\\Test\\PostConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinished.php',
  819. 'PHPUnit\\Event\\Test\\PostConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.php',
  820. 'PHPUnit\\Event\\Test\\PreConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php',
  821. 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php',
  822. 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php',
  823. 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php',
  824. 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php',
  825. 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php',
  826. 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php',
  827. 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php',
  828. 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php',
  829. 'PHPUnit\\Event\\Test\\PreparedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php',
  830. 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutput' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutput.php',
  831. 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutputSubscriber' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.php',
  832. 'PHPUnit\\Event\\Test\\Skipped' => '/phpunit/Event/Events/Test/Outcome/Skipped.php',
  833. 'PHPUnit\\Event\\Test\\SkippedSubscriber' => '/phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php',
  834. 'PHPUnit\\Event\\Test\\TestProxyCreated' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreated.php',
  835. 'PHPUnit\\Event\\Test\\TestProxyCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php',
  836. 'PHPUnit\\Event\\Test\\TestStubCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreated.php',
  837. 'PHPUnit\\Event\\Test\\TestStubCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php',
  838. 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.php',
  839. 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.php',
  840. 'PHPUnit\\Event\\Test\\WarningTriggered' => '/phpunit/Event/Events/Test/Issue/WarningTriggered.php',
  841. 'PHPUnit\\Event\\Test\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php',
  842. 'PHPUnit\\Event\\Tracer\\Tracer' => '/phpunit/Event/Tracer.php',
  843. 'PHPUnit\\Event\\TypeMap' => '/phpunit/Event/TypeMap.php',
  844. 'PHPUnit\\Event\\UnknownEventException' => '/phpunit/Event/Exception/UnknownEventException.php',
  845. 'PHPUnit\\Event\\UnknownEventTypeException' => '/phpunit/Event/Exception/UnknownEventTypeException.php',
  846. 'PHPUnit\\Event\\UnknownSubscriberException' => '/phpunit/Event/Exception/UnknownSubscriberException.php',
  847. 'PHPUnit\\Event\\UnknownSubscriberTypeException' => '/phpunit/Event/Exception/UnknownSubscriberTypeException.php',
  848. 'PHPUnit\\Exception' => '/phpunit/Exception.php',
  849. 'PHPUnit\\Framework\\ActualValueIsNotAnObjectException' => '/phpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php',
  850. 'PHPUnit\\Framework\\Assert' => '/phpunit/Framework/Assert.php',
  851. 'PHPUnit\\Framework\\AssertionFailedError' => '/phpunit/Framework/Exception/AssertionFailedError.php',
  852. 'PHPUnit\\Framework\\Attributes\\After' => '/phpunit/Framework/Attributes/After.php',
  853. 'PHPUnit\\Framework\\Attributes\\AfterClass' => '/phpunit/Framework/Attributes/AfterClass.php',
  854. 'PHPUnit\\Framework\\Attributes\\BackupGlobals' => '/phpunit/Framework/Attributes/BackupGlobals.php',
  855. 'PHPUnit\\Framework\\Attributes\\BackupStaticProperties' => '/phpunit/Framework/Attributes/BackupStaticProperties.php',
  856. 'PHPUnit\\Framework\\Attributes\\Before' => '/phpunit/Framework/Attributes/Before.php',
  857. 'PHPUnit\\Framework\\Attributes\\BeforeClass' => '/phpunit/Framework/Attributes/BeforeClass.php',
  858. 'PHPUnit\\Framework\\Attributes\\CodeCoverageIgnore' => '/phpunit/Framework/Attributes/CodeCoverageIgnore.php',
  859. 'PHPUnit\\Framework\\Attributes\\CoversClass' => '/phpunit/Framework/Attributes/CoversClass.php',
  860. 'PHPUnit\\Framework\\Attributes\\CoversFunction' => '/phpunit/Framework/Attributes/CoversFunction.php',
  861. 'PHPUnit\\Framework\\Attributes\\CoversNothing' => '/phpunit/Framework/Attributes/CoversNothing.php',
  862. 'PHPUnit\\Framework\\Attributes\\DataProvider' => '/phpunit/Framework/Attributes/DataProvider.php',
  863. 'PHPUnit\\Framework\\Attributes\\DataProviderExternal' => '/phpunit/Framework/Attributes/DataProviderExternal.php',
  864. 'PHPUnit\\Framework\\Attributes\\Depends' => '/phpunit/Framework/Attributes/Depends.php',
  865. 'PHPUnit\\Framework\\Attributes\\DependsExternal' => '/phpunit/Framework/Attributes/DependsExternal.php',
  866. 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingDeepClone' => '/phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php',
  867. 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingShallowClone' => '/phpunit/Framework/Attributes/DependsExternalUsingShallowClone.php',
  868. 'PHPUnit\\Framework\\Attributes\\DependsOnClass' => '/phpunit/Framework/Attributes/DependsOnClass.php',
  869. 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingDeepClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php',
  870. 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingShallowClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php',
  871. 'PHPUnit\\Framework\\Attributes\\DependsUsingDeepClone' => '/phpunit/Framework/Attributes/DependsUsingDeepClone.php',
  872. 'PHPUnit\\Framework\\Attributes\\DependsUsingShallowClone' => '/phpunit/Framework/Attributes/DependsUsingShallowClone.php',
  873. 'PHPUnit\\Framework\\Attributes\\DoesNotPerformAssertions' => '/phpunit/Framework/Attributes/DoesNotPerformAssertions.php',
  874. 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php',
  875. 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php',
  876. 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php',
  877. 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php',
  878. 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php',
  879. 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php',
  880. 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php',
  881. 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php',
  882. 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php',
  883. 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php',
  884. 'PHPUnit\\Framework\\Attributes\\PreCondition' => '/phpunit/Framework/Attributes/PreCondition.php',
  885. 'PHPUnit\\Framework\\Attributes\\PreserveGlobalState' => '/phpunit/Framework/Attributes/PreserveGlobalState.php',
  886. 'PHPUnit\\Framework\\Attributes\\RequiresFunction' => '/phpunit/Framework/Attributes/RequiresFunction.php',
  887. 'PHPUnit\\Framework\\Attributes\\RequiresMethod' => '/phpunit/Framework/Attributes/RequiresMethod.php',
  888. 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem' => '/phpunit/Framework/Attributes/RequiresOperatingSystem.php',
  889. 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily' => '/phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php',
  890. 'PHPUnit\\Framework\\Attributes\\RequiresPhp' => '/phpunit/Framework/Attributes/RequiresPhp.php',
  891. 'PHPUnit\\Framework\\Attributes\\RequiresPhpExtension' => '/phpunit/Framework/Attributes/RequiresPhpExtension.php',
  892. 'PHPUnit\\Framework\\Attributes\\RequiresPhpunit' => '/phpunit/Framework/Attributes/RequiresPhpunit.php',
  893. 'PHPUnit\\Framework\\Attributes\\RequiresSetting' => '/phpunit/Framework/Attributes/RequiresSetting.php',
  894. 'PHPUnit\\Framework\\Attributes\\RunClassInSeparateProcess' => '/phpunit/Framework/Attributes/RunClassInSeparateProcess.php',
  895. 'PHPUnit\\Framework\\Attributes\\RunInSeparateProcess' => '/phpunit/Framework/Attributes/RunInSeparateProcess.php',
  896. 'PHPUnit\\Framework\\Attributes\\RunTestsInSeparateProcesses' => '/phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php',
  897. 'PHPUnit\\Framework\\Attributes\\Small' => '/phpunit/Framework/Attributes/Small.php',
  898. 'PHPUnit\\Framework\\Attributes\\Test' => '/phpunit/Framework/Attributes/Test.php',
  899. 'PHPUnit\\Framework\\Attributes\\TestDox' => '/phpunit/Framework/Attributes/TestDox.php',
  900. 'PHPUnit\\Framework\\Attributes\\TestWith' => '/phpunit/Framework/Attributes/TestWith.php',
  901. 'PHPUnit\\Framework\\Attributes\\TestWithJson' => '/phpunit/Framework/Attributes/TestWithJson.php',
  902. 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php',
  903. 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php',
  904. 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php',
  905. 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php',
  906. 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php',
  907. 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php',
  908. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php',
  909. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareExactlyOneParameterException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php',
  910. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.php',
  911. 'PHPUnit\\Framework\\ComparisonMethodDoesNotExistException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php',
  912. 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => '/phpunit/Framework/Constraint/Traversable/ArrayHasKey.php',
  913. 'PHPUnit\\Framework\\Constraint\\BinaryOperator' => '/phpunit/Framework/Constraint/Operator/BinaryOperator.php',
  914. 'PHPUnit\\Framework\\Constraint\\Callback' => '/phpunit/Framework/Constraint/Callback.php',
  915. 'PHPUnit\\Framework\\Constraint\\Constraint' => '/phpunit/Framework/Constraint/Constraint.php',
  916. 'PHPUnit\\Framework\\Constraint\\Count' => '/phpunit/Framework/Constraint/Cardinality/Count.php',
  917. 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => '/phpunit/Framework/Constraint/Filesystem/DirectoryExists.php',
  918. 'PHPUnit\\Framework\\Constraint\\Exception' => '/phpunit/Framework/Constraint/Exception/Exception.php',
  919. 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => '/phpunit/Framework/Constraint/Exception/ExceptionCode.php',
  920. 'PHPUnit\\Framework\\Constraint\\ExceptionMessageIsOrContains' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php',
  921. 'PHPUnit\\Framework\\Constraint\\ExceptionMessageMatchesRegularExpression' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php',
  922. 'PHPUnit\\Framework\\Constraint\\FileExists' => '/phpunit/Framework/Constraint/Filesystem/FileExists.php',
  923. 'PHPUnit\\Framework\\Constraint\\GreaterThan' => '/phpunit/Framework/Constraint/Cardinality/GreaterThan.php',
  924. 'PHPUnit\\Framework\\Constraint\\IsAnything' => '/phpunit/Framework/Constraint/IsAnything.php',
  925. 'PHPUnit\\Framework\\Constraint\\IsEmpty' => '/phpunit/Framework/Constraint/Cardinality/IsEmpty.php',
  926. 'PHPUnit\\Framework\\Constraint\\IsEqual' => '/phpunit/Framework/Constraint/Equality/IsEqual.php',
  927. 'PHPUnit\\Framework\\Constraint\\IsEqualCanonicalizing' => '/phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php',
  928. 'PHPUnit\\Framework\\Constraint\\IsEqualIgnoringCase' => '/phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php',
  929. 'PHPUnit\\Framework\\Constraint\\IsEqualWithDelta' => '/phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php',
  930. 'PHPUnit\\Framework\\Constraint\\IsFalse' => '/phpunit/Framework/Constraint/Boolean/IsFalse.php',
  931. 'PHPUnit\\Framework\\Constraint\\IsFinite' => '/phpunit/Framework/Constraint/Math/IsFinite.php',
  932. 'PHPUnit\\Framework\\Constraint\\IsIdentical' => '/phpunit/Framework/Constraint/IsIdentical.php',
  933. 'PHPUnit\\Framework\\Constraint\\IsInfinite' => '/phpunit/Framework/Constraint/Math/IsInfinite.php',
  934. 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => '/phpunit/Framework/Constraint/Type/IsInstanceOf.php',
  935. 'PHPUnit\\Framework\\Constraint\\IsJson' => '/phpunit/Framework/Constraint/String/IsJson.php',
  936. 'PHPUnit\\Framework\\Constraint\\IsList' => '/phpunit/Framework/Constraint/Traversable/IsList.php',
  937. 'PHPUnit\\Framework\\Constraint\\IsNan' => '/phpunit/Framework/Constraint/Math/IsNan.php',
  938. 'PHPUnit\\Framework\\Constraint\\IsNull' => '/phpunit/Framework/Constraint/Type/IsNull.php',
  939. 'PHPUnit\\Framework\\Constraint\\IsReadable' => '/phpunit/Framework/Constraint/Filesystem/IsReadable.php',
  940. 'PHPUnit\\Framework\\Constraint\\IsTrue' => '/phpunit/Framework/Constraint/Boolean/IsTrue.php',
  941. 'PHPUnit\\Framework\\Constraint\\IsType' => '/phpunit/Framework/Constraint/Type/IsType.php',
  942. 'PHPUnit\\Framework\\Constraint\\IsWritable' => '/phpunit/Framework/Constraint/Filesystem/IsWritable.php',
  943. 'PHPUnit\\Framework\\Constraint\\JsonMatches' => '/phpunit/Framework/Constraint/JsonMatches.php',
  944. 'PHPUnit\\Framework\\Constraint\\LessThan' => '/phpunit/Framework/Constraint/Cardinality/LessThan.php',
  945. 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => '/phpunit/Framework/Constraint/Operator/LogicalAnd.php',
  946. 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php',
  947. 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php',
  948. 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php',
  949. 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php',
  950. 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php',
  951. 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php',
  952. 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php',
  953. 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php',
  954. 'PHPUnit\\Framework\\Constraint\\StringContains' => '/phpunit/Framework/Constraint/String/StringContains.php',
  955. 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => '/phpunit/Framework/Constraint/String/StringEndsWith.php',
  956. 'PHPUnit\\Framework\\Constraint\\StringEqualsStringIgnoringLineEndings' => '/phpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php',
  957. 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => '/phpunit/Framework/Constraint/String/StringMatchesFormatDescription.php',
  958. 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => '/phpunit/Framework/Constraint/String/StringStartsWith.php',
  959. 'PHPUnit\\Framework\\Constraint\\TraversableContains' => '/phpunit/Framework/Constraint/Traversable/TraversableContains.php',
  960. 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php',
  961. 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.php',
  962. 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php',
  963. 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php',
  964. 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php',
  965. 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php',
  966. 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php',
  967. 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php',
  968. 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php',
  969. 'PHPUnit\\Framework\\GeneratorNotSupportedException' => '/phpunit/Framework/Exception/GeneratorNotSupportedException.php',
  970. 'PHPUnit\\Framework\\IncompleteTest' => '/phpunit/Framework/Exception/Incomplete/IncompleteTest.php',
  971. 'PHPUnit\\Framework\\IncompleteTestError' => '/phpunit/Framework/Exception/Incomplete/IncompleteTestError.php',
  972. 'PHPUnit\\Framework\\InvalidArgumentException' => '/phpunit/Framework/Exception/InvalidArgumentException.php',
  973. 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php',
  974. 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php',
  975. 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php',
  976. 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php',
  977. 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php',
  978. 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php',
  979. 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php',
  980. 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php',
  981. 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php',
  982. 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php',
  983. 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php',
  984. 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php',
  985. 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php',
  986. 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php',
  987. 'PHPUnit\\Framework\\MockObject\\Generator\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.php',
  988. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php',
  989. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php',
  990. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php',
  991. 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php',
  992. 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php',
  993. 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php',
  994. 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php',
  995. 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php',
  996. 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php',
  997. 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php',
  998. 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php',
  999. 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php',
  1000. 'PHPUnit\\Framework\\MockObject\\Generator\\NameAlreadyInUseException' => '/phpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.php',
  1001. 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php',
  1002. 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php',
  1003. 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php',
  1004. 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php',
  1005. 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php',
  1006. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php',
  1007. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php',
  1008. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php',
  1009. 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php',
  1010. 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php',
  1011. 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php',
  1012. 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php',
  1013. 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php',
  1014. 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php',
  1015. 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php',
  1016. 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php',
  1017. 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php',
  1018. 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php',
  1019. 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php',
  1020. 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php',
  1021. 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php',
  1022. 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php',
  1023. 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php',
  1024. 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php',
  1025. 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php',
  1026. 'PHPUnit\\Framework\\MockObject\\NoMoreReturnValuesConfiguredException' => '/phpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php',
  1027. 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php',
  1028. 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php',
  1029. 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php',
  1030. 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php',
  1031. 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php',
  1032. 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php',
  1033. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php',
  1034. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php',
  1035. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php',
  1036. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php',
  1037. 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php',
  1038. 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php',
  1039. 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php',
  1040. 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php',
  1041. 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php',
  1042. 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php',
  1043. 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php',
  1044. 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php',
  1045. 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php',
  1046. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php',
  1047. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php',
  1048. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php',
  1049. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php',
  1050. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php',
  1051. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php',
  1052. 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php',
  1053. 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php',
  1054. 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php',
  1055. 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php',
  1056. 'PHPUnit\\Framework\\Reorderable' => '/phpunit/Framework/Reorderable.php',
  1057. 'PHPUnit\\Framework\\SelfDescribing' => '/phpunit/Framework/SelfDescribing.php',
  1058. 'PHPUnit\\Framework\\SkippedTest' => '/phpunit/Framework/Exception/Skipped/SkippedTest.php',
  1059. 'PHPUnit\\Framework\\SkippedTestSuiteError' => '/phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.php',
  1060. 'PHPUnit\\Framework\\SkippedWithMessageException' => '/phpunit/Framework/Exception/Skipped/SkippedWithMessageException.php',
  1061. 'PHPUnit\\Framework\\Test' => '/phpunit/Framework/Test.php',
  1062. 'PHPUnit\\Framework\\TestBuilder' => '/phpunit/Framework/TestBuilder.php',
  1063. 'PHPUnit\\Framework\\TestCase' => '/phpunit/Framework/TestCase.php',
  1064. 'PHPUnit\\Framework\\TestRunner' => '/phpunit/Framework/TestRunner.php',
  1065. 'PHPUnit\\Framework\\TestSize\\Known' => '/phpunit/Framework/TestSize/Known.php',
  1066. 'PHPUnit\\Framework\\TestSize\\Large' => '/phpunit/Framework/TestSize/Large.php',
  1067. 'PHPUnit\\Framework\\TestSize\\Medium' => '/phpunit/Framework/TestSize/Medium.php',
  1068. 'PHPUnit\\Framework\\TestSize\\Small' => '/phpunit/Framework/TestSize/Small.php',
  1069. 'PHPUnit\\Framework\\TestSize\\TestSize' => '/phpunit/Framework/TestSize/TestSize.php',
  1070. 'PHPUnit\\Framework\\TestSize\\Unknown' => '/phpunit/Framework/TestSize/Unknown.php',
  1071. 'PHPUnit\\Framework\\TestStatus\\Deprecation' => '/phpunit/Framework/TestStatus/Deprecation.php',
  1072. 'PHPUnit\\Framework\\TestStatus\\Error' => '/phpunit/Framework/TestStatus/Error.php',
  1073. 'PHPUnit\\Framework\\TestStatus\\Failure' => '/phpunit/Framework/TestStatus/Failure.php',
  1074. 'PHPUnit\\Framework\\TestStatus\\Incomplete' => '/phpunit/Framework/TestStatus/Incomplete.php',
  1075. 'PHPUnit\\Framework\\TestStatus\\Known' => '/phpunit/Framework/TestStatus/Known.php',
  1076. 'PHPUnit\\Framework\\TestStatus\\Notice' => '/phpunit/Framework/TestStatus/Notice.php',
  1077. 'PHPUnit\\Framework\\TestStatus\\Risky' => '/phpunit/Framework/TestStatus/Risky.php',
  1078. 'PHPUnit\\Framework\\TestStatus\\Skipped' => '/phpunit/Framework/TestStatus/Skipped.php',
  1079. 'PHPUnit\\Framework\\TestStatus\\Success' => '/phpunit/Framework/TestStatus/Success.php',
  1080. 'PHPUnit\\Framework\\TestStatus\\TestStatus' => '/phpunit/Framework/TestStatus/TestStatus.php',
  1081. 'PHPUnit\\Framework\\TestStatus\\Unknown' => '/phpunit/Framework/TestStatus/Unknown.php',
  1082. 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php',
  1083. 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php',
  1084. 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php',
  1085. 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php',
  1086. 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php',
  1087. 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php',
  1088. 'PHPUnit\\Logging\\JUnit\\JunitXmlLogger' => '/phpunit/Logging/JUnit/JunitXmlLogger.php',
  1089. 'PHPUnit\\Logging\\JUnit\\Subscriber' => '/phpunit/Logging/JUnit/Subscriber/Subscriber.php',
  1090. 'PHPUnit\\Logging\\JUnit\\TestErroredSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.php',
  1091. 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php',
  1092. 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php',
  1093. 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php',
  1094. 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php',
  1095. 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php',
  1096. 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php',
  1097. 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
  1098. 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php',
  1099. 'PHPUnit\\Logging\\JUnit\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php',
  1100. 'PHPUnit\\Logging\\JUnit\\TestSuiteStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php',
  1101. 'PHPUnit\\Logging\\TeamCity\\Subscriber' => '/phpunit/Logging/TeamCity/Subscriber/Subscriber.php',
  1102. 'PHPUnit\\Logging\\TeamCity\\TeamCityLogger' => '/phpunit/Logging/TeamCity/TeamCityLogger.php',
  1103. 'PHPUnit\\Logging\\TeamCity\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php',
  1104. 'PHPUnit\\Logging\\TeamCity\\TestErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.php',
  1105. 'PHPUnit\\Logging\\TeamCity\\TestFailedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php',
  1106. 'PHPUnit\\Logging\\TeamCity\\TestFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php',
  1107. 'PHPUnit\\Logging\\TeamCity\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php',
  1108. 'PHPUnit\\Logging\\TeamCity\\TestPreparedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php',
  1109. 'PHPUnit\\Logging\\TeamCity\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
  1110. 'PHPUnit\\Logging\\TeamCity\\TestSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.php',
  1111. 'PHPUnit\\Logging\\TeamCity\\TestSuiteBeforeFirstTestMethodErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.php',
  1112. 'PHPUnit\\Logging\\TeamCity\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php',
  1113. 'PHPUnit\\Logging\\TeamCity\\TestSuiteSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.php',
  1114. 'PHPUnit\\Logging\\TeamCity\\TestSuiteStartedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php',
  1115. 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php',
  1116. 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php',
  1117. 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php',
  1118. 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php',
  1119. 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
  1120. 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php',
  1121. 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php',
  1122. 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php',
  1123. 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
  1124. 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php',
  1125. 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php',
  1126. 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php',
  1127. 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php',
  1128. 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php',
  1129. 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php',
  1130. 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php',
  1131. 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
  1132. 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
  1133. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  1134. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  1135. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  1136. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  1137. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
  1138. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  1139. 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
  1140. 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php',
  1141. 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php',
  1142. 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php',
  1143. 'PHPUnit\\Metadata\\Annotation\\Parser\\Registry' => '/phpunit/Metadata/Parser/Annotation/Registry.php',
  1144. 'PHPUnit\\Metadata\\AnnotationsAreNotSupportedForInternalClassesException' => '/phpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php',
  1145. 'PHPUnit\\Metadata\\Api\\CodeCoverage' => '/phpunit/Metadata/Api/CodeCoverage.php',
  1146. 'PHPUnit\\Metadata\\Api\\DataProvider' => '/phpunit/Metadata/Api/DataProvider.php',
  1147. 'PHPUnit\\Metadata\\Api\\Dependencies' => '/phpunit/Metadata/Api/Dependencies.php',
  1148. 'PHPUnit\\Metadata\\Api\\Groups' => '/phpunit/Metadata/Api/Groups.php',
  1149. 'PHPUnit\\Metadata\\Api\\HookMethods' => '/phpunit/Metadata/Api/HookMethods.php',
  1150. 'PHPUnit\\Metadata\\Api\\Requirements' => '/phpunit/Metadata/Api/Requirements.php',
  1151. 'PHPUnit\\Metadata\\BackupGlobals' => '/phpunit/Metadata/BackupGlobals.php',
  1152. 'PHPUnit\\Metadata\\BackupStaticProperties' => '/phpunit/Metadata/BackupStaticProperties.php',
  1153. 'PHPUnit\\Metadata\\Before' => '/phpunit/Metadata/Before.php',
  1154. 'PHPUnit\\Metadata\\BeforeClass' => '/phpunit/Metadata/BeforeClass.php',
  1155. 'PHPUnit\\Metadata\\Covers' => '/phpunit/Metadata/Covers.php',
  1156. 'PHPUnit\\Metadata\\CoversClass' => '/phpunit/Metadata/CoversClass.php',
  1157. 'PHPUnit\\Metadata\\CoversDefaultClass' => '/phpunit/Metadata/CoversDefaultClass.php',
  1158. 'PHPUnit\\Metadata\\CoversFunction' => '/phpunit/Metadata/CoversFunction.php',
  1159. 'PHPUnit\\Metadata\\CoversNothing' => '/phpunit/Metadata/CoversNothing.php',
  1160. 'PHPUnit\\Metadata\\DataProvider' => '/phpunit/Metadata/DataProvider.php',
  1161. 'PHPUnit\\Metadata\\DependsOnClass' => '/phpunit/Metadata/DependsOnClass.php',
  1162. 'PHPUnit\\Metadata\\DependsOnMethod' => '/phpunit/Metadata/DependsOnMethod.php',
  1163. 'PHPUnit\\Metadata\\DoesNotPerformAssertions' => '/phpunit/Metadata/DoesNotPerformAssertions.php',
  1164. 'PHPUnit\\Metadata\\Exception' => '/phpunit/Metadata/Exception/Exception.php',
  1165. 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php',
  1166. 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php',
  1167. 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php',
  1168. 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php',
  1169. 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php',
  1170. 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php',
  1171. 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php',
  1172. 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php',
  1173. 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php',
  1174. 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php',
  1175. 'PHPUnit\\Metadata\\MetadataCollectionIterator' => '/phpunit/Metadata/MetadataCollectionIterator.php',
  1176. 'PHPUnit\\Metadata\\NoVersionRequirementException' => '/phpunit/Metadata/Exception/NoVersionRequirementException.php',
  1177. 'PHPUnit\\Metadata\\Parser\\AnnotationParser' => '/phpunit/Metadata/Parser/AnnotationParser.php',
  1178. 'PHPUnit\\Metadata\\Parser\\AttributeParser' => '/phpunit/Metadata/Parser/AttributeParser.php',
  1179. 'PHPUnit\\Metadata\\Parser\\CachingParser' => '/phpunit/Metadata/Parser/CachingParser.php',
  1180. 'PHPUnit\\Metadata\\Parser\\Parser' => '/phpunit/Metadata/Parser/Parser.php',
  1181. 'PHPUnit\\Metadata\\Parser\\ParserChain' => '/phpunit/Metadata/Parser/ParserChain.php',
  1182. 'PHPUnit\\Metadata\\Parser\\Registry' => '/phpunit/Metadata/Parser/Registry.php',
  1183. 'PHPUnit\\Metadata\\PostCondition' => '/phpunit/Metadata/PostCondition.php',
  1184. 'PHPUnit\\Metadata\\PreCondition' => '/phpunit/Metadata/PreCondition.php',
  1185. 'PHPUnit\\Metadata\\PreserveGlobalState' => '/phpunit/Metadata/PreserveGlobalState.php',
  1186. 'PHPUnit\\Metadata\\ReflectionException' => '/phpunit/Metadata/Exception/ReflectionException.php',
  1187. 'PHPUnit\\Metadata\\RequiresFunction' => '/phpunit/Metadata/RequiresFunction.php',
  1188. 'PHPUnit\\Metadata\\RequiresMethod' => '/phpunit/Metadata/RequiresMethod.php',
  1189. 'PHPUnit\\Metadata\\RequiresOperatingSystem' => '/phpunit/Metadata/RequiresOperatingSystem.php',
  1190. 'PHPUnit\\Metadata\\RequiresOperatingSystemFamily' => '/phpunit/Metadata/RequiresOperatingSystemFamily.php',
  1191. 'PHPUnit\\Metadata\\RequiresPhp' => '/phpunit/Metadata/RequiresPhp.php',
  1192. 'PHPUnit\\Metadata\\RequiresPhpExtension' => '/phpunit/Metadata/RequiresPhpExtension.php',
  1193. 'PHPUnit\\Metadata\\RequiresPhpunit' => '/phpunit/Metadata/RequiresPhpunit.php',
  1194. 'PHPUnit\\Metadata\\RequiresSetting' => '/phpunit/Metadata/RequiresSetting.php',
  1195. 'PHPUnit\\Metadata\\RunClassInSeparateProcess' => '/phpunit/Metadata/RunClassInSeparateProcess.php',
  1196. 'PHPUnit\\Metadata\\RunInSeparateProcess' => '/phpunit/Metadata/RunInSeparateProcess.php',
  1197. 'PHPUnit\\Metadata\\RunTestsInSeparateProcesses' => '/phpunit/Metadata/RunTestsInSeparateProcesses.php',
  1198. 'PHPUnit\\Metadata\\Test' => '/phpunit/Metadata/Test.php',
  1199. 'PHPUnit\\Metadata\\TestDox' => '/phpunit/Metadata/TestDox.php',
  1200. 'PHPUnit\\Metadata\\TestWith' => '/phpunit/Metadata/TestWith.php',
  1201. 'PHPUnit\\Metadata\\Uses' => '/phpunit/Metadata/Uses.php',
  1202. 'PHPUnit\\Metadata\\UsesClass' => '/phpunit/Metadata/UsesClass.php',
  1203. 'PHPUnit\\Metadata\\UsesDefaultClass' => '/phpunit/Metadata/UsesDefaultClass.php',
  1204. 'PHPUnit\\Metadata\\UsesFunction' => '/phpunit/Metadata/UsesFunction.php',
  1205. 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php',
  1206. 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php',
  1207. 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php',
  1208. 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php',
  1209. 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php',
  1210. 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php',
  1211. 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php',
  1212. 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php',
  1213. 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php',
  1214. 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php',
  1215. 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php',
  1216. 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php',
  1217. 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php',
  1218. 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php',
  1219. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  1220. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  1221. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  1222. 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php',
  1223. 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php',
  1224. 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php',
  1225. 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php',
  1226. 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php',
  1227. 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php',
  1228. 'PHPUnit\\Runner\\DirectoryDoesNotExistException' => '/phpunit/Runner/Exception/DirectoryDoesNotExistException.php',
  1229. 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php',
  1230. 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php',
  1231. 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php',
  1232. 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php',
  1233. 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php',
  1234. 'PHPUnit\\Runner\\Extension\\Facade' => '/phpunit/Runner/Extension/Facade.php',
  1235. 'PHPUnit\\Runner\\Extension\\ParameterCollection' => '/phpunit/Runner/Extension/ParameterCollection.php',
  1236. 'PHPUnit\\Runner\\Extension\\PharLoader' => '/phpunit/Runner/Extension/PharLoader.php',
  1237. 'PHPUnit\\Runner\\FileDoesNotExistException' => '/phpunit/Runner/Exception/FileDoesNotExistException.php',
  1238. 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => '/phpunit/Runner/Filter/ExcludeGroupFilterIterator.php',
  1239. 'PHPUnit\\Runner\\Filter\\Factory' => '/phpunit/Runner/Filter/Factory.php',
  1240. 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php',
  1241. 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php',
  1242. 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php',
  1243. 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php',
  1244. 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php',
  1245. 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php',
  1246. 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php',
  1247. 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php',
  1248. 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php',
  1249. 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php',
  1250. 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php',
  1251. 'PHPUnit\\Runner\\ParameterDoesNotExistException' => '/phpunit/Runner/Exception/ParameterDoesNotExistException.php',
  1252. 'PHPUnit\\Runner\\PhptExternalFileCannotBeLoadedException' => '/phpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.php',
  1253. 'PHPUnit\\Runner\\PhptTestCase' => '/phpunit/Runner/PhptTestCase.php',
  1254. 'PHPUnit\\Runner\\ResultCache\\DefaultResultCache' => '/phpunit/Runner/ResultCache/DefaultResultCache.php',
  1255. 'PHPUnit\\Runner\\ResultCache\\NullResultCache' => '/phpunit/Runner/ResultCache/NullResultCache.php',
  1256. 'PHPUnit\\Runner\\ResultCache\\ResultCache' => '/phpunit/Runner/ResultCache/ResultCache.php',
  1257. 'PHPUnit\\Runner\\ResultCache\\ResultCacheHandler' => '/phpunit/Runner/ResultCache/ResultCacheHandler.php',
  1258. 'PHPUnit\\Runner\\ResultCache\\Subscriber' => '/phpunit/Runner/ResultCache/Subscriber/Subscriber.php',
  1259. 'PHPUnit\\Runner\\ResultCache\\TestConsideredRiskySubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.php',
  1260. 'PHPUnit\\Runner\\ResultCache\\TestErroredSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php',
  1261. 'PHPUnit\\Runner\\ResultCache\\TestFailedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php',
  1262. 'PHPUnit\\Runner\\ResultCache\\TestFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.php',
  1263. 'PHPUnit\\Runner\\ResultCache\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.php',
  1264. 'PHPUnit\\Runner\\ResultCache\\TestPreparedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php',
  1265. 'PHPUnit\\Runner\\ResultCache\\TestSkippedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.php',
  1266. 'PHPUnit\\Runner\\ResultCache\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php',
  1267. 'PHPUnit\\Runner\\ResultCache\\TestSuiteStartedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php',
  1268. 'PHPUnit\\Runner\\TestSuiteLoader' => '/phpunit/Runner/TestSuiteLoader.php',
  1269. 'PHPUnit\\Runner\\TestSuiteSorter' => '/phpunit/Runner/TestSuiteSorter.php',
  1270. 'PHPUnit\\Runner\\UnsupportedPhptSectionException' => '/phpunit/Runner/Exception/UnsupportedPhptSectionException.php',
  1271. 'PHPUnit\\Runner\\Version' => '/phpunit/Runner/Version.php',
  1272. 'PHPUnit\\TestRunner\\TestResult\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
  1273. 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php',
  1274. 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php',
  1275. 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php',
  1276. 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php',
  1277. 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php',
  1278. 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php',
  1279. 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
  1280. 'PHPUnit\\TestRunner\\TestResult\\TestErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php',
  1281. 'PHPUnit\\TestRunner\\TestResult\\TestFailedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php',
  1282. 'PHPUnit\\TestRunner\\TestResult\\TestFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php',
  1283. 'PHPUnit\\TestRunner\\TestResult\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
  1284. 'PHPUnit\\TestRunner\\TestResult\\TestPreparedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php',
  1285. 'PHPUnit\\TestRunner\\TestResult\\TestResult' => '/phpunit/Runner/TestResult/TestResult.php',
  1286. 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php',
  1287. 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.php',
  1288. 'PHPUnit\\TestRunner\\TestResult\\TestSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php',
  1289. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php',
  1290. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php',
  1291. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php',
  1292. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
  1293. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.php',
  1294. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
  1295. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  1296. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  1297. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  1298. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  1299. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
  1300. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  1301. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
  1302. 'PHPUnit\\TextUI\\Application' => '/phpunit/TextUI/Application.php',
  1303. 'PHPUnit\\TextUI\\CannotOpenSocketException' => '/phpunit/TextUI/Exception/CannotOpenSocketException.php',
  1304. 'PHPUnit\\TextUI\\CliArguments\\Builder' => '/phpunit/TextUI/Configuration/Cli/Builder.php',
  1305. 'PHPUnit\\TextUI\\CliArguments\\Configuration' => '/phpunit/TextUI/Configuration/Cli/Configuration.php',
  1306. 'PHPUnit\\TextUI\\CliArguments\\Exception' => '/phpunit/TextUI/Configuration/Cli/Exception.php',
  1307. 'PHPUnit\\TextUI\\CliArguments\\XmlConfigurationFileFinder' => '/phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.php',
  1308. 'PHPUnit\\TextUI\\Command\\AtLeastVersionCommand' => '/phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php',
  1309. 'PHPUnit\\TextUI\\Command\\Command' => '/phpunit/TextUI/Command/Command.php',
  1310. 'PHPUnit\\TextUI\\Command\\GenerateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php',
  1311. 'PHPUnit\\TextUI\\Command\\ListGroupsCommand' => '/phpunit/TextUI/Command/Commands/ListGroupsCommand.php',
  1312. 'PHPUnit\\TextUI\\Command\\ListTestSuitesCommand' => '/phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php',
  1313. 'PHPUnit\\TextUI\\Command\\ListTestsAsTextCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.php',
  1314. 'PHPUnit\\TextUI\\Command\\ListTestsAsXmlCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php',
  1315. 'PHPUnit\\TextUI\\Command\\MigrateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php',
  1316. 'PHPUnit\\TextUI\\Command\\Result' => '/phpunit/TextUI/Command/Result.php',
  1317. 'PHPUnit\\TextUI\\Command\\ShowHelpCommand' => '/phpunit/TextUI/Command/Commands/ShowHelpCommand.php',
  1318. 'PHPUnit\\TextUI\\Command\\ShowVersionCommand' => '/phpunit/TextUI/Command/Commands/ShowVersionCommand.php',
  1319. 'PHPUnit\\TextUI\\Command\\VersionCheckCommand' => '/phpunit/TextUI/Command/Commands/VersionCheckCommand.php',
  1320. 'PHPUnit\\TextUI\\Command\\WarmCodeCoverageCacheCommand' => '/phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
  1321. 'PHPUnit\\TextUI\\Configuration\\Builder' => '/phpunit/TextUI/Configuration/Builder.php',
  1322. 'PHPUnit\\TextUI\\Configuration\\CodeCoverageFilterRegistry' => '/phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php',
  1323. 'PHPUnit\\TextUI\\Configuration\\CodeCoverageReportNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php',
  1324. 'PHPUnit\\TextUI\\Configuration\\Configuration' => '/phpunit/TextUI/Configuration/Configuration.php',
  1325. 'PHPUnit\\TextUI\\Configuration\\ConfigurationCannotBeBuiltException' => '/phpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php',
  1326. 'PHPUnit\\TextUI\\Configuration\\Constant' => '/phpunit/TextUI/Configuration/Value/Constant.php',
  1327. 'PHPUnit\\TextUI\\Configuration\\ConstantCollection' => '/phpunit/TextUI/Configuration/Value/ConstantCollection.php',
  1328. 'PHPUnit\\TextUI\\Configuration\\ConstantCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php',
  1329. 'PHPUnit\\TextUI\\Configuration\\Directory' => '/phpunit/TextUI/Configuration/Value/Directory.php',
  1330. 'PHPUnit\\TextUI\\Configuration\\DirectoryCollection' => '/phpunit/TextUI/Configuration/Value/DirectoryCollection.php',
  1331. 'PHPUnit\\TextUI\\Configuration\\DirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php',
  1332. 'PHPUnit\\TextUI\\Configuration\\Exception' => '/phpunit/TextUI/Configuration/Exception/Exception.php',
  1333. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrap' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php',
  1334. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollection' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php',
  1335. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php',
  1336. 'PHPUnit\\TextUI\\Configuration\\File' => '/phpunit/TextUI/Configuration/Value/File.php',
  1337. 'PHPUnit\\TextUI\\Configuration\\FileCollection' => '/phpunit/TextUI/Configuration/Value/FileCollection.php',
  1338. 'PHPUnit\\TextUI\\Configuration\\FileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FileCollectionIterator.php',
  1339. 'PHPUnit\\TextUI\\Configuration\\FilterDirectory' => '/phpunit/TextUI/Configuration/Value/FilterDirectory.php',
  1340. 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php',
  1341. 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.php',
  1342. 'PHPUnit\\TextUI\\Configuration\\FilterNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php',
  1343. 'PHPUnit\\TextUI\\Configuration\\Group' => '/phpunit/TextUI/Configuration/Value/Group.php',
  1344. 'PHPUnit\\TextUI\\Configuration\\GroupCollection' => '/phpunit/TextUI/Configuration/Value/GroupCollection.php',
  1345. 'PHPUnit\\TextUI\\Configuration\\GroupCollectionIterator' => '/phpunit/TextUI/Configuration/Value/GroupCollectionIterator.php',
  1346. 'PHPUnit\\TextUI\\Configuration\\IniSetting' => '/phpunit/TextUI/Configuration/Value/IniSetting.php',
  1347. 'PHPUnit\\TextUI\\Configuration\\IniSettingCollection' => '/phpunit/TextUI/Configuration/Value/IniSettingCollection.php',
  1348. 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php',
  1349. 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php',
  1350. 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php',
  1351. 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php',
  1352. 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php',
  1353. 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php',
  1354. 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php',
  1355. 'PHPUnit\\TextUI\\Configuration\\NoConfigurationFileException' => '/phpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php',
  1356. 'PHPUnit\\TextUI\\Configuration\\NoCoverageCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php',
  1357. 'PHPUnit\\TextUI\\Configuration\\NoCustomCssFileException' => '/phpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php',
  1358. 'PHPUnit\\TextUI\\Configuration\\NoDefaultTestSuiteException' => '/phpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.php',
  1359. 'PHPUnit\\TextUI\\Configuration\\NoPharExtensionDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php',
  1360. 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php',
  1361. 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php',
  1362. 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php',
  1363. 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php',
  1364. 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php',
  1365. 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php',
  1366. 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php',
  1367. 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php',
  1368. 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php',
  1369. 'PHPUnit\\TextUI\\Configuration\\TestFile' => '/phpunit/TextUI/Configuration/Value/TestFile.php',
  1370. 'PHPUnit\\TextUI\\Configuration\\TestFileCollection' => '/phpunit/TextUI/Configuration/Value/TestFileCollection.php',
  1371. 'PHPUnit\\TextUI\\Configuration\\TestFileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php',
  1372. 'PHPUnit\\TextUI\\Configuration\\TestSuite' => '/phpunit/TextUI/Configuration/Value/TestSuite.php',
  1373. 'PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder' => '/phpunit/TextUI/Configuration/TestSuiteBuilder.php',
  1374. 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollection' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollection.php',
  1375. 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.php',
  1376. 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php',
  1377. 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php',
  1378. 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php',
  1379. 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php',
  1380. 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php',
  1381. 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php',
  1382. 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php',
  1383. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
  1384. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php',
  1385. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\Subscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php',
  1386. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestConsideredRiskySubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.php',
  1387. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.php',
  1388. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFailedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php',
  1389. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php',
  1390. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php',
  1391. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php',
  1392. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php',
  1393. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
  1394. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php',
  1395. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php',
  1396. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php',
  1397. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  1398. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  1399. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  1400. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  1401. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  1402. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php',
  1403. 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php',
  1404. 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php',
  1405. 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php',
  1406. 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php',
  1407. 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php',
  1408. 'PHPUnit\\TextUI\\Output\\SummaryPrinter' => '/phpunit/TextUI/Output/SummaryPrinter.php',
  1409. 'PHPUnit\\TextUI\\Output\\TestDox\\ResultPrinter' => '/phpunit/TextUI/Output/TestDox/ResultPrinter.php',
  1410. 'PHPUnit\\TextUI\\RuntimeException' => '/phpunit/TextUI/Exception/RuntimeException.php',
  1411. 'PHPUnit\\TextUI\\ShellExitCodeCalculator' => '/phpunit/TextUI/ShellExitCodeCalculator.php',
  1412. 'PHPUnit\\TextUI\\TestDirectoryNotFoundException' => '/phpunit/TextUI/Exception/TestDirectoryNotFoundException.php',
  1413. 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php',
  1414. 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php',
  1415. 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php',
  1416. 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php',
  1417. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php',
  1418. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php',
  1419. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php',
  1420. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Crap4j' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.php',
  1421. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Html' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php',
  1422. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Php' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php',
  1423. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Text' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php',
  1424. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Xml' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php',
  1425. 'PHPUnit\\TextUI\\XmlConfiguration\\Configuration' => '/phpunit/TextUI/Configuration/Xml/Configuration.php',
  1426. 'PHPUnit\\TextUI\\XmlConfiguration\\ConvertLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php',
  1427. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCloverToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.php',
  1428. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCrap4jToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php',
  1429. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageHtmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php',
  1430. 'PHPUnit\\TextUI\\XmlConfiguration\\CoveragePhpToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php',
  1431. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageTextToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php',
  1432. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php',
  1433. 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php',
  1434. 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php',
  1435. 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php',
  1436. 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php',
  1437. 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php',
  1438. 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php',
  1439. 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCoverageElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.php',
  1440. 'PHPUnit\\TextUI\\XmlConfiguration\\LoadedFromFileConfiguration' => '/phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php',
  1441. 'PHPUnit\\TextUI\\XmlConfiguration\\Loader' => '/phpunit/TextUI/Configuration/Xml/Loader.php',
  1442. 'PHPUnit\\TextUI\\XmlConfiguration\\LogToReportMigration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.php',
  1443. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Junit' => '/phpunit/TextUI/Configuration/Xml/Logging/Junit.php',
  1444. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Logging' => '/phpunit/TextUI/Configuration/Xml/Logging/Logging.php',
  1445. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TeamCity' => '/phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php',
  1446. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Html' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php',
  1447. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Text' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php',
  1448. 'PHPUnit\\TextUI\\XmlConfiguration\\Migration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php',
  1449. 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationBuilder' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php',
  1450. 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationException' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationException.php',
  1451. 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php',
  1452. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php',
  1453. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php',
  1454. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php',
  1455. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php',
  1456. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php',
  1457. 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php',
  1458. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php',
  1459. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php',
  1460. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheResultFileAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php',
  1461. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheTokensAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php',
  1462. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveConversionToExceptionsAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php',
  1463. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.php',
  1464. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementProcessUncoveredFilesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php',
  1465. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveEmptyFilter' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php',
  1466. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveListeners' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php',
  1467. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.php',
  1468. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLoggingElements' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php',
  1469. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveNoInteractionAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php',
  1470. 'PHPUnit\\TextUI\\XmlConfiguration\\RemovePrinterAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php',
  1471. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestDoxGroupsElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php',
  1472. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestSuiteLoaderAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php',
  1473. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveVerboseAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php',
  1474. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php',
  1475. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php',
  1476. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php',
  1477. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php',
  1478. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php',
  1479. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php',
  1480. 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php',
  1481. 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php',
  1482. 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php',
  1483. 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php',
  1484. 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php',
  1485. 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php',
  1486. 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php',
  1487. 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php',
  1488. 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php',
  1489. 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php',
  1490. 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php',
  1491. 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php',
  1492. 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php',
  1493. 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php',
  1494. 'PHPUnit\\Util\\Http\\Downloader' => '/phpunit/Util/Http/Downloader.php',
  1495. 'PHPUnit\\Util\\Http\\PhpDownloader' => '/phpunit/Util/Http/PhpDownloader.php',
  1496. 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php',
  1497. 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php',
  1498. 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php',
  1499. 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php',
  1500. 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php',
  1501. 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php',
  1502. 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php',
  1503. 'PHPUnit\\Util\\Reflection' => '/phpunit/Util/Reflection.php',
  1504. 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php',
  1505. 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php',
  1506. 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php',
  1507. 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php',
  1508. 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php',
  1509. 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php'];
  1510. }
  1511. if (isset($classes[$class])) {
  1512. require_once 'phar://phpunit-10.5.40.phar' . $classes[$class];
  1513. }
  1514. },
  1515. true,
  1516. false
  1517. );
  1518. foreach (['PHPUnitPHAR\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy.php',
  1519. 'PHPUnitPHAR\\DeepCopy\\Exception\\CloneException' => '/myclabs-deep-copy/DeepCopy/Exception/CloneException.php',
  1520. 'PHPUnitPHAR\\DeepCopy\\Exception\\PropertyException' => '/myclabs-deep-copy/DeepCopy/Exception/PropertyException.php',
  1521. 'PHPUnitPHAR\\DeepCopy\\Filter\\ChainableFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.php',
  1522. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php',
  1523. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php',
  1524. 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php',
  1525. 'PHPUnitPHAR\\DeepCopy\\Filter\\Filter' => '/myclabs-deep-copy/DeepCopy/Filter/Filter.php',
  1526. 'PHPUnitPHAR\\DeepCopy\\Filter\\KeepFilter' => '/myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php',
  1527. 'PHPUnitPHAR\\DeepCopy\\Filter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php',
  1528. 'PHPUnitPHAR\\DeepCopy\\Filter\\SetNullFilter' => '/myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php',
  1529. 'PHPUnitPHAR\\DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php',
  1530. 'PHPUnitPHAR\\DeepCopy\\Matcher\\Matcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Matcher.php',
  1531. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php',
  1532. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyNameMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php',
  1533. 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyTypeMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php',
  1534. 'PHPUnitPHAR\\DeepCopy\\Reflection\\ReflectionHelper' => '/myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php',
  1535. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php',
  1536. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DatePeriodFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php',
  1537. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php',
  1538. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ShallowCopyFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php',
  1539. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\ArrayObjectFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php',
  1540. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php',
  1541. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php',
  1542. 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\TypeFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php',
  1543. 'PHPUnitPHAR\\DeepCopy\\TypeMatcher\\TypeMatcher' => '/myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php',
  1544. 'PHPUnitPHAR\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php',
  1545. 'PHPUnitPHAR\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php',
  1546. 'PHPUnitPHAR\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php',
  1547. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollection' => '/phar-io-manifest/values/AuthorCollection.php',
  1548. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollectionIterator' => '/phar-io-manifest/values/AuthorCollectionIterator.php',
  1549. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElement' => '/phar-io-manifest/xml/AuthorElement.php',
  1550. 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElementCollection' => '/phar-io-manifest/xml/AuthorElementCollection.php',
  1551. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponent' => '/phar-io-manifest/values/BundledComponent.php',
  1552. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollection' => '/phar-io-manifest/values/BundledComponentCollection.php',
  1553. 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollectionIterator' => '/phar-io-manifest/values/BundledComponentCollectionIterator.php',
  1554. 'PHPUnitPHAR\\PharIo\\Manifest\\BundlesElement' => '/phar-io-manifest/xml/BundlesElement.php',
  1555. 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElement' => '/phar-io-manifest/xml/ComponentElement.php',
  1556. 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElementCollection' => '/phar-io-manifest/xml/ComponentElementCollection.php',
  1557. 'PHPUnitPHAR\\PharIo\\Manifest\\ContainsElement' => '/phar-io-manifest/xml/ContainsElement.php',
  1558. 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightElement' => '/phar-io-manifest/xml/CopyrightElement.php',
  1559. 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightInformation' => '/phar-io-manifest/values/CopyrightInformation.php',
  1560. 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollection' => '/phar-io-manifest/xml/ElementCollection.php',
  1561. 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollectionException' => '/phar-io-manifest/exceptions/ElementCollectionException.php',
  1562. 'PHPUnitPHAR\\PharIo\\Manifest\\Email' => '/phar-io-manifest/values/Email.php',
  1563. 'PHPUnitPHAR\\PharIo\\Manifest\\Exception' => '/phar-io-manifest/exceptions/Exception.php',
  1564. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElement' => '/phar-io-manifest/xml/ExtElement.php',
  1565. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElementCollection' => '/phar-io-manifest/xml/ExtElementCollection.php',
  1566. 'PHPUnitPHAR\\PharIo\\Manifest\\Extension' => '/phar-io-manifest/values/Extension.php',
  1567. 'PHPUnitPHAR\\PharIo\\Manifest\\ExtensionElement' => '/phar-io-manifest/xml/ExtensionElement.php',
  1568. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidApplicationNameException' => '/phar-io-manifest/exceptions/InvalidApplicationNameException.php',
  1569. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidEmailException' => '/phar-io-manifest/exceptions/InvalidEmailException.php',
  1570. 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidUrlException' => '/phar-io-manifest/exceptions/InvalidUrlException.php',
  1571. 'PHPUnitPHAR\\PharIo\\Manifest\\Library' => '/phar-io-manifest/values/Library.php',
  1572. 'PHPUnitPHAR\\PharIo\\Manifest\\License' => '/phar-io-manifest/values/License.php',
  1573. 'PHPUnitPHAR\\PharIo\\Manifest\\LicenseElement' => '/phar-io-manifest/xml/LicenseElement.php',
  1574. 'PHPUnitPHAR\\PharIo\\Manifest\\Manifest' => '/phar-io-manifest/values/Manifest.php',
  1575. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocument' => '/phar-io-manifest/xml/ManifestDocument.php',
  1576. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentException' => '/phar-io-manifest/exceptions/ManifestDocumentException.php',
  1577. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentLoadingException' => '/phar-io-manifest/exceptions/ManifestDocumentLoadingException.php',
  1578. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapper' => '/phar-io-manifest/ManifestDocumentMapper.php',
  1579. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapperException' => '/phar-io-manifest/exceptions/ManifestDocumentMapperException.php',
  1580. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElement' => '/phar-io-manifest/xml/ManifestElement.php',
  1581. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElementException' => '/phar-io-manifest/exceptions/ManifestElementException.php',
  1582. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoader' => '/phar-io-manifest/ManifestLoader.php',
  1583. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoaderException' => '/phar-io-manifest/exceptions/ManifestLoaderException.php',
  1584. 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestSerializer' => '/phar-io-manifest/ManifestSerializer.php',
  1585. 'PHPUnitPHAR\\PharIo\\Manifest\\NoEmailAddressException' => '/phar-io-manifest/exceptions/NoEmailAddressException.php',
  1586. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpElement' => '/phar-io-manifest/xml/PhpElement.php',
  1587. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpExtensionRequirement' => '/phar-io-manifest/values/PhpExtensionRequirement.php',
  1588. 'PHPUnitPHAR\\PharIo\\Manifest\\PhpVersionRequirement' => '/phar-io-manifest/values/PhpVersionRequirement.php',
  1589. 'PHPUnitPHAR\\PharIo\\Manifest\\Requirement' => '/phar-io-manifest/values/Requirement.php',
  1590. 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollection' => '/phar-io-manifest/values/RequirementCollection.php',
  1591. 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollectionIterator' => '/phar-io-manifest/values/RequirementCollectionIterator.php',
  1592. 'PHPUnitPHAR\\PharIo\\Manifest\\RequiresElement' => '/phar-io-manifest/xml/RequiresElement.php',
  1593. 'PHPUnitPHAR\\PharIo\\Manifest\\Type' => '/phar-io-manifest/values/Type.php',
  1594. 'PHPUnitPHAR\\PharIo\\Manifest\\Url' => '/phar-io-manifest/values/Url.php',
  1595. 'PHPUnitPHAR\\PharIo\\Version\\AbstractVersionConstraint' => '/phar-io-version/constraints/AbstractVersionConstraint.php',
  1596. 'PHPUnitPHAR\\PharIo\\Version\\AndVersionConstraintGroup' => '/phar-io-version/constraints/AndVersionConstraintGroup.php',
  1597. 'PHPUnitPHAR\\PharIo\\Version\\AnyVersionConstraint' => '/phar-io-version/constraints/AnyVersionConstraint.php',
  1598. 'PHPUnitPHAR\\PharIo\\Version\\BuildMetaData' => '/phar-io-version/BuildMetaData.php',
  1599. 'PHPUnitPHAR\\PharIo\\Version\\ExactVersionConstraint' => '/phar-io-version/constraints/ExactVersionConstraint.php',
  1600. 'PHPUnitPHAR\\PharIo\\Version\\Exception' => '/phar-io-version/exceptions/Exception.php',
  1601. 'PHPUnitPHAR\\PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => '/phar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php',
  1602. 'PHPUnitPHAR\\PharIo\\Version\\InvalidPreReleaseSuffixException' => '/phar-io-version/exceptions/InvalidPreReleaseSuffixException.php',
  1603. 'PHPUnitPHAR\\PharIo\\Version\\InvalidVersionException' => '/phar-io-version/exceptions/InvalidVersionException.php',
  1604. 'PHPUnitPHAR\\PharIo\\Version\\NoBuildMetaDataException' => '/phar-io-version/exceptions/NoBuildMetaDataException.php',
  1605. 'PHPUnitPHAR\\PharIo\\Version\\NoPreReleaseSuffixException' => '/phar-io-version/exceptions/NoPreReleaseSuffixException.php',
  1606. 'PHPUnitPHAR\\PharIo\\Version\\OrVersionConstraintGroup' => '/phar-io-version/constraints/OrVersionConstraintGroup.php',
  1607. 'PHPUnitPHAR\\PharIo\\Version\\PreReleaseSuffix' => '/phar-io-version/PreReleaseSuffix.php',
  1608. 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.php',
  1609. 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorVersionConstraint.php',
  1610. 'PHPUnitPHAR\\PharIo\\Version\\UnsupportedVersionConstraintException' => '/phar-io-version/exceptions/UnsupportedVersionConstraintException.php',
  1611. 'PHPUnitPHAR\\PharIo\\Version\\Version' => '/phar-io-version/Version.php',
  1612. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraint' => '/phar-io-version/constraints/VersionConstraint.php',
  1613. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintParser' => '/phar-io-version/VersionConstraintParser.php',
  1614. 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintValue' => '/phar-io-version/VersionConstraintValue.php',
  1615. 'PHPUnitPHAR\\PharIo\\Version\\VersionNumber' => '/phar-io-version/VersionNumber.php',
  1616. 'PHPUnitPHAR\\PhpParser\\Builder' => '/nikic-php-parser/PhpParser/Builder.php',
  1617. 'PHPUnitPHAR\\PhpParser\\BuilderFactory' => '/nikic-php-parser/PhpParser/BuilderFactory.php',
  1618. 'PHPUnitPHAR\\PhpParser\\BuilderHelpers' => '/nikic-php-parser/PhpParser/BuilderHelpers.php',
  1619. 'PHPUnitPHAR\\PhpParser\\Builder\\ClassConst' => '/nikic-php-parser/PhpParser/Builder/ClassConst.php',
  1620. 'PHPUnitPHAR\\PhpParser\\Builder\\Class_' => '/nikic-php-parser/PhpParser/Builder/Class_.php',
  1621. 'PHPUnitPHAR\\PhpParser\\Builder\\Declaration' => '/nikic-php-parser/PhpParser/Builder/Declaration.php',
  1622. 'PHPUnitPHAR\\PhpParser\\Builder\\EnumCase' => '/nikic-php-parser/PhpParser/Builder/EnumCase.php',
  1623. 'PHPUnitPHAR\\PhpParser\\Builder\\Enum_' => '/nikic-php-parser/PhpParser/Builder/Enum_.php',
  1624. 'PHPUnitPHAR\\PhpParser\\Builder\\FunctionLike' => '/nikic-php-parser/PhpParser/Builder/FunctionLike.php',
  1625. 'PHPUnitPHAR\\PhpParser\\Builder\\Function_' => '/nikic-php-parser/PhpParser/Builder/Function_.php',
  1626. 'PHPUnitPHAR\\PhpParser\\Builder\\Interface_' => '/nikic-php-parser/PhpParser/Builder/Interface_.php',
  1627. 'PHPUnitPHAR\\PhpParser\\Builder\\Method' => '/nikic-php-parser/PhpParser/Builder/Method.php',
  1628. 'PHPUnitPHAR\\PhpParser\\Builder\\Namespace_' => '/nikic-php-parser/PhpParser/Builder/Namespace_.php',
  1629. 'PHPUnitPHAR\\PhpParser\\Builder\\Param' => '/nikic-php-parser/PhpParser/Builder/Param.php',
  1630. 'PHPUnitPHAR\\PhpParser\\Builder\\Property' => '/nikic-php-parser/PhpParser/Builder/Property.php',
  1631. 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUse' => '/nikic-php-parser/PhpParser/Builder/TraitUse.php',
  1632. 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.php',
  1633. 'PHPUnitPHAR\\PhpParser\\Builder\\Trait_' => '/nikic-php-parser/PhpParser/Builder/Trait_.php',
  1634. 'PHPUnitPHAR\\PhpParser\\Builder\\Use_' => '/nikic-php-parser/PhpParser/Builder/Use_.php',
  1635. 'PHPUnitPHAR\\PhpParser\\Comment' => '/nikic-php-parser/PhpParser/Comment.php',
  1636. 'PHPUnitPHAR\\PhpParser\\Comment\\Doc' => '/nikic-php-parser/PhpParser/Comment/Doc.php',
  1637. 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluationException' => '/nikic-php-parser/PhpParser/ConstExprEvaluationException.php',
  1638. 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluator' => '/nikic-php-parser/PhpParser/ConstExprEvaluator.php',
  1639. 'PHPUnitPHAR\\PhpParser\\Error' => '/nikic-php-parser/PhpParser/Error.php',
  1640. 'PHPUnitPHAR\\PhpParser\\ErrorHandler' => '/nikic-php-parser/PhpParser/ErrorHandler.php',
  1641. 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Collecting' => '/nikic-php-parser/PhpParser/ErrorHandler/Collecting.php',
  1642. 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Throwing' => '/nikic-php-parser/PhpParser/ErrorHandler/Throwing.php',
  1643. 'PHPUnitPHAR\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php',
  1644. 'PHPUnitPHAR\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php',
  1645. 'PHPUnitPHAR\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php',
  1646. 'PHPUnitPHAR\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php',
  1647. 'PHPUnitPHAR\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php',
  1648. 'PHPUnitPHAR\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php',
  1649. 'PHPUnitPHAR\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php',
  1650. 'PHPUnitPHAR\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php',
  1651. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AsymmetricVisibilityTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php',
  1652. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
  1653. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
  1654. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
  1655. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
  1656. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
  1657. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
  1658. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PropertyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php',
  1659. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
  1660. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
  1661. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
  1662. 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
  1663. 'PHPUnitPHAR\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php',
  1664. 'PHPUnitPHAR\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php',
  1665. 'PHPUnitPHAR\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php',
  1666. 'PHPUnitPHAR\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php',
  1667. 'PHPUnitPHAR\\PhpParser\\NodeDumper' => '/nikic-php-parser/PhpParser/NodeDumper.php',
  1668. 'PHPUnitPHAR\\PhpParser\\NodeFinder' => '/nikic-php-parser/PhpParser/NodeFinder.php',
  1669. 'PHPUnitPHAR\\PhpParser\\NodeTraverser' => '/nikic-php-parser/PhpParser/NodeTraverser.php',
  1670. 'PHPUnitPHAR\\PhpParser\\NodeTraverserInterface' => '/nikic-php-parser/PhpParser/NodeTraverserInterface.php',
  1671. 'PHPUnitPHAR\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php',
  1672. 'PHPUnitPHAR\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php',
  1673. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php',
  1674. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php',
  1675. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php',
  1676. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php',
  1677. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php',
  1678. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
  1679. 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
  1680. 'PHPUnitPHAR\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php',
  1681. 'PHPUnitPHAR\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php',
  1682. 'PHPUnitPHAR\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php',
  1683. 'PHPUnitPHAR\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php',
  1684. 'PHPUnitPHAR\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php',
  1685. 'PHPUnitPHAR\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php',
  1686. 'PHPUnitPHAR\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php',
  1687. 'PHPUnitPHAR\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php',
  1688. 'PHPUnitPHAR\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php',
  1689. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php',
  1690. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php',
  1691. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php',
  1692. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php',
  1693. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp.php',
  1694. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
  1695. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
  1696. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
  1697. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php',
  1698. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.php',
  1699. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.php',
  1700. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.php',
  1701. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.php',
  1702. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.php',
  1703. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.php',
  1704. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.php',
  1705. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
  1706. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
  1707. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignRef' => '/nikic-php-parser/PhpParser/Node/Expr/AssignRef.php',
  1708. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp.php',
  1709. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
  1710. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
  1711. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
  1712. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
  1713. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
  1714. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
  1715. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.php',
  1716. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.php',
  1717. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.php',
  1718. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.php',
  1719. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
  1720. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.php',
  1721. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
  1722. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
  1723. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
  1724. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.php',
  1725. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.php',
  1726. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.php',
  1727. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
  1728. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
  1729. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.php',
  1730. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.php',
  1731. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
  1732. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
  1733. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.php',
  1734. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
  1735. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
  1736. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BitwiseNot' => '/nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php',
  1737. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BooleanNot' => '/nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php',
  1738. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\CallLike' => '/nikic-php-parser/PhpParser/Node/Expr/CallLike.php',
  1739. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast' => '/nikic-php-parser/PhpParser/Node/Expr/Cast.php',
  1740. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.php',
  1741. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Bool_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.php',
  1742. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Double' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php',
  1743. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Int_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.php',
  1744. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Object_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.php',
  1745. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\String_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/String_.php',
  1746. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Unset_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.php',
  1747. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php',
  1748. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php',
  1749. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php',
  1750. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php',
  1751. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php',
  1752. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php',
  1753. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ErrorSuppress' => '/nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php',
  1754. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Eval_' => '/nikic-php-parser/PhpParser/Node/Expr/Eval_.php',
  1755. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Exit_' => '/nikic-php-parser/PhpParser/Node/Expr/Exit_.php',
  1756. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\FuncCall' => '/nikic-php-parser/PhpParser/Node/Expr/FuncCall.php',
  1757. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Include_' => '/nikic-php-parser/PhpParser/Node/Expr/Include_.php',
  1758. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Instanceof_' => '/nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php',
  1759. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Isset_' => '/nikic-php-parser/PhpParser/Node/Expr/Isset_.php',
  1760. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\List_' => '/nikic-php-parser/PhpParser/Node/Expr/List_.php',
  1761. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Match_' => '/nikic-php-parser/PhpParser/Node/Expr/Match_.php',
  1762. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\MethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/MethodCall.php',
  1763. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\New_' => '/nikic-php-parser/PhpParser/Node/Expr/New_.php',
  1764. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.php',
  1765. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php',
  1766. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostDec' => '/nikic-php-parser/PhpParser/Node/Expr/PostDec.php',
  1767. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostInc' => '/nikic-php-parser/PhpParser/Node/Expr/PostInc.php',
  1768. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreDec' => '/nikic-php-parser/PhpParser/Node/Expr/PreDec.php',
  1769. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreInc' => '/nikic-php-parser/PhpParser/Node/Expr/PreInc.php',
  1770. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Print_' => '/nikic-php-parser/PhpParser/Node/Expr/Print_.php',
  1771. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.php',
  1772. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ShellExec' => '/nikic-php-parser/PhpParser/Node/Expr/ShellExec.php',
  1773. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticCall' => '/nikic-php-parser/PhpParser/Node/Expr/StaticCall.php',
  1774. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php',
  1775. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Ternary' => '/nikic-php-parser/PhpParser/Node/Expr/Ternary.php',
  1776. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Throw_' => '/nikic-php-parser/PhpParser/Node/Expr/Throw_.php',
  1777. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryMinus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php',
  1778. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryPlus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.php',
  1779. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Variable' => '/nikic-php-parser/PhpParser/Node/Expr/Variable.php',
  1780. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\YieldFrom' => '/nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php',
  1781. 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php',
  1782. 'PHPUnitPHAR\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php',
  1783. 'PHPUnitPHAR\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php',
  1784. 'PHPUnitPHAR\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php',
  1785. 'PHPUnitPHAR\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php',
  1786. 'PHPUnitPHAR\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php',
  1787. 'PHPUnitPHAR\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php',
  1788. 'PHPUnitPHAR\\PhpParser\\Node\\Name\\FullyQualified' => '/nikic-php-parser/PhpParser/Node/Name/FullyQualified.php',
  1789. 'PHPUnitPHAR\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php',
  1790. 'PHPUnitPHAR\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php',
  1791. 'PHPUnitPHAR\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php',
  1792. 'PHPUnitPHAR\\PhpParser\\Node\\PropertyHook' => '/nikic-php-parser/PhpParser/Node/PropertyHook.php',
  1793. 'PHPUnitPHAR\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php',
  1794. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php',
  1795. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php',
  1796. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php',
  1797. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php',
  1798. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php',
  1799. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php',
  1800. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php',
  1801. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\File' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.php',
  1802. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php',
  1803. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.php',
  1804. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php',
  1805. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
  1806. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Property' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.php',
  1807. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php',
  1808. 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php',
  1809. 'PHPUnitPHAR\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php',
  1810. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php',
  1811. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php',
  1812. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php',
  1813. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php',
  1814. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php',
  1815. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassConst' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassConst.php',
  1816. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassLike' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php',
  1817. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassMethod' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php',
  1818. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php',
  1819. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php',
  1820. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php',
  1821. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php',
  1822. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php',
  1823. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php',
  1824. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ElseIf_' => '/nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php',
  1825. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Else_' => '/nikic-php-parser/PhpParser/Node/Stmt/Else_.php',
  1826. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\EnumCase' => '/nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php',
  1827. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Enum_' => '/nikic-php-parser/PhpParser/Node/Stmt/Enum_.php',
  1828. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Expression' => '/nikic-php-parser/PhpParser/Node/Stmt/Expression.php',
  1829. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Finally_' => '/nikic-php-parser/PhpParser/Node/Stmt/Finally_.php',
  1830. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\For_' => '/nikic-php-parser/PhpParser/Node/Stmt/For_.php',
  1831. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Foreach_' => '/nikic-php-parser/PhpParser/Node/Stmt/Foreach_.php',
  1832. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Function_' => '/nikic-php-parser/PhpParser/Node/Stmt/Function_.php',
  1833. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Global_' => '/nikic-php-parser/PhpParser/Node/Stmt/Global_.php',
  1834. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Goto_' => '/nikic-php-parser/PhpParser/Node/Stmt/Goto_.php',
  1835. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\GroupUse' => '/nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php',
  1836. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\HaltCompiler' => '/nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php',
  1837. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\If_' => '/nikic-php-parser/PhpParser/Node/Stmt/If_.php',
  1838. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\InlineHTML' => '/nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php',
  1839. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Interface_' => '/nikic-php-parser/PhpParser/Node/Stmt/Interface_.php',
  1840. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Label' => '/nikic-php-parser/PhpParser/Node/Stmt/Label.php',
  1841. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php',
  1842. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php',
  1843. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php',
  1844. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php',
  1845. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php',
  1846. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php',
  1847. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php',
  1848. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php',
  1849. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
  1850. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
  1851. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php',
  1852. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php',
  1853. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php',
  1854. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php',
  1855. 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php',
  1856. 'PHPUnitPHAR\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php',
  1857. 'PHPUnitPHAR\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php',
  1858. 'PHPUnitPHAR\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php',
  1859. 'PHPUnitPHAR\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php',
  1860. 'PHPUnitPHAR\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php',
  1861. 'PHPUnitPHAR\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php',
  1862. 'PHPUnitPHAR\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php',
  1863. 'PHPUnitPHAR\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php',
  1864. 'PHPUnitPHAR\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php',
  1865. 'PHPUnitPHAR\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php',
  1866. 'PHPUnitPHAR\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php',
  1867. 'PHPUnitPHAR\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php',
  1868. 'PHPUnitPHAR\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php',
  1869. 'PHPUnitPHAR\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php',
  1870. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\AmbiguousOptionException' => '/sebastian-cli-parser/exceptions/AmbiguousOptionException.php',
  1871. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Exception' => '/sebastian-cli-parser/exceptions/Exception.php',
  1872. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\OptionDoesNotAllowArgumentException' => '/sebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.php',
  1873. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Parser' => '/sebastian-cli-parser/Parser.php',
  1874. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\RequiredOptionArgumentMissingException' => '/sebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.php',
  1875. 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\UnknownOptionException' => '/sebastian-cli-parser/exceptions/UnknownOptionException.php',
  1876. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\BranchAndPathCoverageNotSupportedException' => '/php-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.php',
  1877. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\CodeCoverage' => '/php-code-coverage/CodeCoverage.php',
  1878. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\ProcessedCodeCoverageData' => '/php-code-coverage/Data/ProcessedCodeCoverageData.php',
  1879. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\RawCodeCoverageData' => '/php-code-coverage/Data/RawCodeCoverageData.php',
  1880. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\DeadCodeDetectionNotSupportedException' => '/php-code-coverage/Exception/DeadCodeDetectionNotSupportedException.php',
  1881. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Driver' => '/php-code-coverage/Driver/Driver.php',
  1882. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PathExistsButIsNotDirectoryException' => '/php-code-coverage/Exception/PathExistsButIsNotDirectoryException.php',
  1883. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovDriver' => '/php-code-coverage/Driver/PcovDriver.php',
  1884. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovNotAvailableException' => '/php-code-coverage/Exception/PcovNotAvailableException.php',
  1885. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Selector' => '/php-code-coverage/Driver/Selector.php',
  1886. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\WriteOperationFailedException' => '/php-code-coverage/Exception/WriteOperationFailedException.php',
  1887. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugDriver' => '/php-code-coverage/Driver/XdebugDriver.php',
  1888. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php',
  1889. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php',
  1890. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php',
  1891. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php',
  1892. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php',
  1893. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php',
  1894. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php',
  1895. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverWithPathCoverageSupportAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.php',
  1896. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => '/php-code-coverage/Node/AbstractNode.php',
  1897. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Builder' => '/php-code-coverage/Node/Builder.php',
  1898. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\CrapIndex' => '/php-code-coverage/Node/CrapIndex.php',
  1899. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Directory' => '/php-code-coverage/Node/Directory.php',
  1900. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\File' => '/php-code-coverage/Node/File.php',
  1901. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Iterator' => '/php-code-coverage/Node/Iterator.php',
  1902. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ParserException' => '/php-code-coverage/Exception/ParserException.php',
  1903. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReflectionException' => '/php-code-coverage/Exception/ReflectionException.php',
  1904. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReportAlreadyFinalizedException' => '/php-code-coverage/Exception/ReportAlreadyFinalizedException.php',
  1905. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Clover' => '/php-code-coverage/Report/Clover.php',
  1906. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Cobertura' => '/php-code-coverage/Report/Cobertura.php',
  1907. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => '/php-code-coverage/Report/Crap4j.php',
  1908. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Colors' => '/php-code-coverage/Report/Html/Colors.php',
  1909. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\CustomCssFile' => '/php-code-coverage/Report/Html/CustomCssFile.php',
  1910. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => '/php-code-coverage/Report/Html/Renderer/Dashboard.php',
  1911. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => '/php-code-coverage/Report/Html/Renderer/Directory.php',
  1912. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => '/php-code-coverage/Report/Html/Facade.php',
  1913. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => '/php-code-coverage/Report/Html/Renderer/File.php',
  1914. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => '/php-code-coverage/Report/Html/Renderer.php',
  1915. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\PHP' => '/php-code-coverage/Report/PHP.php',
  1916. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Text' => '/php-code-coverage/Report/Text.php',
  1917. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Thresholds' => '/php-code-coverage/Report/Thresholds.php',
  1918. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => '/php-code-coverage/Report/Xml/BuildInformation.php',
  1919. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => '/php-code-coverage/Report/Xml/Coverage.php',
  1920. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => '/php-code-coverage/Report/Xml/Directory.php',
  1921. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => '/php-code-coverage/Report/Xml/Facade.php',
  1922. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => '/php-code-coverage/Report/Xml/File.php',
  1923. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => '/php-code-coverage/Report/Xml/Method.php',
  1924. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => '/php-code-coverage/Report/Xml/Node.php',
  1925. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => '/php-code-coverage/Report/Xml/Project.php',
  1926. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => '/php-code-coverage/Report/Xml/Report.php',
  1927. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => '/php-code-coverage/Report/Xml/Source.php',
  1928. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => '/php-code-coverage/Report/Xml/Tests.php',
  1929. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => '/php-code-coverage/Report/Xml/Totals.php',
  1930. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => '/php-code-coverage/Report/Xml/Unit.php',
  1931. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysisCacheNotConfiguredException' => '/php-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.php',
  1932. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CacheWarmer' => '/php-code-coverage/StaticAnalysis/CacheWarmer.php',
  1933. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CachingFileAnalyser' => '/php-code-coverage/StaticAnalysis/CachingFileAnalyser.php',
  1934. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CodeUnitFindingVisitor' => '/php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php',
  1935. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ExecutableLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php',
  1936. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\FileAnalyser' => '/php-code-coverage/StaticAnalysis/FileAnalyser.php',
  1937. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\IgnoredLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php',
  1938. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParsingFileAnalyser' => '/php-code-coverage/StaticAnalysis/ParsingFileAnalyser.php',
  1939. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\TestIdMissingException' => '/php-code-coverage/Exception/TestIdMissingException.php',
  1940. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Known' => '/php-code-coverage/TestSize/Known.php',
  1941. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Large' => '/php-code-coverage/TestSize/Large.php',
  1942. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Medium' => '/php-code-coverage/TestSize/Medium.php',
  1943. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Small' => '/php-code-coverage/TestSize/Small.php',
  1944. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\TestSize' => '/php-code-coverage/TestSize/TestSize.php',
  1945. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Unknown' => '/php-code-coverage/TestSize/Unknown.php',
  1946. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Failure' => '/php-code-coverage/TestStatus/Failure.php',
  1947. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Known' => '/php-code-coverage/TestStatus/Known.php',
  1948. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Success' => '/php-code-coverage/TestStatus/Success.php',
  1949. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\TestStatus' => '/php-code-coverage/TestStatus/TestStatus.php',
  1950. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Unknown' => '/php-code-coverage/TestStatus/Unknown.php',
  1951. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => '/php-code-coverage/Exception/UnintentionallyCoveredCodeException.php',
  1952. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\DirectoryCouldNotBeCreatedException' => '/php-code-coverage/Exception/DirectoryCouldNotBeCreatedException.php',
  1953. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Filesystem' => '/php-code-coverage/Util/Filesystem.php',
  1954. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Percentage' => '/php-code-coverage/Util/Percentage.php',
  1955. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Version' => '/php-code-coverage/Version.php',
  1956. 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\XmlException' => '/php-code-coverage/Exception/XmlException.php',
  1957. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => '/sebastian-code-unit-reverse-lookup/Wizard.php',
  1958. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassMethodUnit' => '/sebastian-code-unit/ClassMethodUnit.php',
  1959. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassUnit' => '/sebastian-code-unit/ClassUnit.php',
  1960. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnit' => '/sebastian-code-unit/CodeUnit.php',
  1961. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollection' => '/sebastian-code-unit/CodeUnitCollection.php',
  1962. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollectionIterator' => '/sebastian-code-unit/CodeUnitCollectionIterator.php',
  1963. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Exception' => '/sebastian-code-unit/exceptions/Exception.php',
  1964. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FileUnit' => '/sebastian-code-unit/FileUnit.php',
  1965. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FunctionUnit' => '/sebastian-code-unit/FunctionUnit.php',
  1966. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceMethodUnit' => '/sebastian-code-unit/InterfaceMethodUnit.php',
  1967. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceUnit' => '/sebastian-code-unit/InterfaceUnit.php',
  1968. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InvalidCodeUnitException' => '/sebastian-code-unit/exceptions/InvalidCodeUnitException.php',
  1969. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Mapper' => '/sebastian-code-unit/Mapper.php',
  1970. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\NoTraitException' => '/sebastian-code-unit/exceptions/NoTraitException.php',
  1971. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ReflectionException' => '/sebastian-code-unit/exceptions/ReflectionException.php',
  1972. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitMethodUnit' => '/sebastian-code-unit/TraitMethodUnit.php',
  1973. 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitUnit' => '/sebastian-code-unit/TraitUnit.php',
  1974. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ArrayComparator' => '/sebastian-comparator/ArrayComparator.php',
  1975. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Comparator' => '/sebastian-comparator/Comparator.php',
  1976. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ComparisonFailure' => '/sebastian-comparator/ComparisonFailure.php',
  1977. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DOMNodeComparator' => '/sebastian-comparator/DOMNodeComparator.php',
  1978. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DateTimeComparator' => '/sebastian-comparator/DateTimeComparator.php',
  1979. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Exception' => '/sebastian-comparator/exceptions/Exception.php',
  1980. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ExceptionComparator' => '/sebastian-comparator/ExceptionComparator.php',
  1981. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Factory' => '/sebastian-comparator/Factory.php',
  1982. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\MockObjectComparator' => '/sebastian-comparator/MockObjectComparator.php',
  1983. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\NumericComparator' => '/sebastian-comparator/NumericComparator.php',
  1984. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ObjectComparator' => '/sebastian-comparator/ObjectComparator.php',
  1985. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ResourceComparator' => '/sebastian-comparator/ResourceComparator.php',
  1986. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\RuntimeException' => '/sebastian-comparator/exceptions/RuntimeException.php',
  1987. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ScalarComparator' => '/sebastian-comparator/ScalarComparator.php',
  1988. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\SplObjectStorageComparator' => '/sebastian-comparator/SplObjectStorageComparator.php',
  1989. 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\TypeComparator' => '/sebastian-comparator/TypeComparator.php',
  1990. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Calculator' => '/sebastian-complexity/Calculator.php',
  1991. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Complexity' => '/sebastian-complexity/Complexity/Complexity.php',
  1992. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php',
  1993. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollection' => '/sebastian-complexity/Complexity/ComplexityCollection.php',
  1994. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollectionIterator' => '/sebastian-complexity/Complexity/ComplexityCollectionIterator.php',
  1995. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\CyclomaticComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php',
  1996. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Exception' => '/sebastian-complexity/Exception/Exception.php',
  1997. 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\RuntimeException' => '/sebastian-complexity/Exception/RuntimeException.php',
  1998. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Chunk' => '/sebastian-diff/Chunk.php',
  1999. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\ConfigurationException' => '/sebastian-diff/Exception/ConfigurationException.php',
  2000. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Diff' => '/sebastian-diff/Diff.php',
  2001. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Differ' => '/sebastian-diff/Differ.php',
  2002. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Exception' => '/sebastian-diff/Exception/Exception.php',
  2003. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\InvalidArgumentException' => '/sebastian-diff/Exception/InvalidArgumentException.php',
  2004. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Line' => '/sebastian-diff/Line.php',
  2005. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => '/sebastian-diff/LongestCommonSubsequenceCalculator.php',
  2006. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.php',
  2007. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => '/sebastian-diff/Output/AbstractChunkOutputBuilder.php',
  2008. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => '/sebastian-diff/Output/DiffOnlyOutputBuilder.php',
  2009. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => '/sebastian-diff/Output/DiffOutputBuilderInterface.php',
  2010. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => '/sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php',
  2011. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => '/sebastian-diff/Output/UnifiedDiffOutputBuilder.php',
  2012. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Parser' => '/sebastian-diff/Parser.php',
  2013. 'PHPUnitPHAR\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php',
  2014. 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Console' => '/sebastian-environment/Console.php',
  2015. 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Runtime' => '/sebastian-environment/Runtime.php',
  2016. 'PHPUnitPHAR\\SebastianBergmann\\Exporter\\Exporter' => '/sebastian-exporter/Exporter.php',
  2017. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\ExcludeIterator' => '/php-file-iterator/ExcludeIterator.php',
  2018. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Facade' => '/php-file-iterator/Facade.php',
  2019. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Factory' => '/php-file-iterator/Factory.php',
  2020. 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Iterator' => '/php-file-iterator/Iterator.php',
  2021. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\CodeExporter' => '/sebastian-global-state/CodeExporter.php',
  2022. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Exception' => '/sebastian-global-state/exceptions/Exception.php',
  2023. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\ExcludeList' => '/sebastian-global-state/ExcludeList.php',
  2024. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Restorer' => '/sebastian-global-state/Restorer.php',
  2025. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\RuntimeException' => '/sebastian-global-state/exceptions/RuntimeException.php',
  2026. 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Snapshot' => '/sebastian-global-state/Snapshot.php',
  2027. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Exception' => '/php-invoker/exceptions/Exception.php',
  2028. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Invoker' => '/php-invoker/Invoker.php',
  2029. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\ProcessControlExtensionNotLoadedException' => '/php-invoker/exceptions/ProcessControlExtensionNotLoadedException.php',
  2030. 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\TimeoutException' => '/php-invoker/exceptions/TimeoutException.php',
  2031. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Counter' => '/sebastian-lines-of-code/Counter.php',
  2032. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Exception' => '/sebastian-lines-of-code/Exception/Exception.php',
  2033. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\IllogicalValuesException' => '/sebastian-lines-of-code/Exception/IllogicalValuesException.php',
  2034. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LineCountingVisitor' => '/sebastian-lines-of-code/LineCountingVisitor.php',
  2035. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LinesOfCode' => '/sebastian-lines-of-code/LinesOfCode.php',
  2036. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\NegativeValueException' => '/sebastian-lines-of-code/Exception/NegativeValueException.php',
  2037. 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\RuntimeException' => '/sebastian-lines-of-code/Exception/RuntimeException.php',
  2038. 'PHPUnitPHAR\\SebastianBergmann\\ObjectEnumerator\\Enumerator' => '/sebastian-object-enumerator/Enumerator.php',
  2039. 'PHPUnitPHAR\\SebastianBergmann\\ObjectReflector\\ObjectReflector' => '/sebastian-object-reflector/ObjectReflector.php',
  2040. 'PHPUnitPHAR\\SebastianBergmann\\RecursionContext\\Context' => '/sebastian-recursion-context/Context.php',
  2041. 'PHPUnitPHAR\\SebastianBergmann\\Template\\Exception' => '/php-text-template/exceptions/Exception.php',
  2042. 'PHPUnitPHAR\\SebastianBergmann\\Template\\InvalidArgumentException' => '/php-text-template/exceptions/InvalidArgumentException.php',
  2043. 'PHPUnitPHAR\\SebastianBergmann\\Template\\RuntimeException' => '/php-text-template/exceptions/RuntimeException.php',
  2044. 'PHPUnitPHAR\\SebastianBergmann\\Template\\Template' => '/php-text-template/Template.php',
  2045. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Duration' => '/php-timer/Duration.php',
  2046. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Exception' => '/php-timer/exceptions/Exception.php',
  2047. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\NoActiveTimerException' => '/php-timer/exceptions/NoActiveTimerException.php',
  2048. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\ResourceUsageFormatter' => '/php-timer/ResourceUsageFormatter.php',
  2049. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\TimeSinceStartOfRequestNotAvailableException' => '/php-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.php',
  2050. 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Timer' => '/php-timer/Timer.php',
  2051. 'PHPUnitPHAR\\SebastianBergmann\\Type\\CallableType' => '/sebastian-type/type/CallableType.php',
  2052. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Exception' => '/sebastian-type/exception/Exception.php',
  2053. 'PHPUnitPHAR\\SebastianBergmann\\Type\\FalseType' => '/sebastian-type/type/FalseType.php',
  2054. 'PHPUnitPHAR\\SebastianBergmann\\Type\\GenericObjectType' => '/sebastian-type/type/GenericObjectType.php',
  2055. 'PHPUnitPHAR\\SebastianBergmann\\Type\\IntersectionType' => '/sebastian-type/type/IntersectionType.php',
  2056. 'PHPUnitPHAR\\SebastianBergmann\\Type\\IterableType' => '/sebastian-type/type/IterableType.php',
  2057. 'PHPUnitPHAR\\SebastianBergmann\\Type\\MixedType' => '/sebastian-type/type/MixedType.php',
  2058. 'PHPUnitPHAR\\SebastianBergmann\\Type\\NeverType' => '/sebastian-type/type/NeverType.php',
  2059. 'PHPUnitPHAR\\SebastianBergmann\\Type\\NullType' => '/sebastian-type/type/NullType.php',
  2060. 'PHPUnitPHAR\\SebastianBergmann\\Type\\ObjectType' => '/sebastian-type/type/ObjectType.php',
  2061. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Parameter' => '/sebastian-type/Parameter.php',
  2062. 'PHPUnitPHAR\\SebastianBergmann\\Type\\ReflectionMapper' => '/sebastian-type/ReflectionMapper.php',
  2063. 'PHPUnitPHAR\\SebastianBergmann\\Type\\RuntimeException' => '/sebastian-type/exception/RuntimeException.php',
  2064. 'PHPUnitPHAR\\SebastianBergmann\\Type\\SimpleType' => '/sebastian-type/type/SimpleType.php',
  2065. 'PHPUnitPHAR\\SebastianBergmann\\Type\\StaticType' => '/sebastian-type/type/StaticType.php',
  2066. 'PHPUnitPHAR\\SebastianBergmann\\Type\\TrueType' => '/sebastian-type/type/TrueType.php',
  2067. 'PHPUnitPHAR\\SebastianBergmann\\Type\\Type' => '/sebastian-type/type/Type.php',
  2068. 'PHPUnitPHAR\\SebastianBergmann\\Type\\TypeName' => '/sebastian-type/TypeName.php',
  2069. 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnionType' => '/sebastian-type/type/UnionType.php',
  2070. 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnknownType' => '/sebastian-type/type/UnknownType.php',
  2071. 'PHPUnitPHAR\\SebastianBergmann\\Type\\VoidType' => '/sebastian-type/type/VoidType.php',
  2072. 'PHPUnitPHAR\\SebastianBergmann\\Version' => '/sebastian-version/Version.php',
  2073. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php',
  2074. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php',
  2075. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php',
  2076. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Token' => '/theseer-tokenizer/Token.php',
  2077. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollection' => '/theseer-tokenizer/TokenCollection.php',
  2078. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollectionException' => '/theseer-tokenizer/TokenCollectionException.php',
  2079. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Tokenizer' => '/theseer-tokenizer/Tokenizer.php',
  2080. 'PHPUnitPHAR\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php',
  2081. 'PHPUnit\\Event\\Application\\Finished' => '/phpunit/Event/Events/Application/Finished.php',
  2082. 'PHPUnit\\Event\\Application\\FinishedSubscriber' => '/phpunit/Event/Events/Application/FinishedSubscriber.php',
  2083. 'PHPUnit\\Event\\Application\\Started' => '/phpunit/Event/Events/Application/Started.php',
  2084. 'PHPUnit\\Event\\Application\\StartedSubscriber' => '/phpunit/Event/Events/Application/StartedSubscriber.php',
  2085. 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php',
  2086. 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php',
  2087. 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php',
  2088. 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php',
  2089. 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php',
  2090. 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php',
  2091. 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php',
  2092. 'PHPUnit\\Event\\Code\\TestCollectionIterator' => '/phpunit/Event/Value/Test/TestCollectionIterator.php',
  2093. 'PHPUnit\\Event\\Code\\TestDox' => '/phpunit/Event/Value/Test/TestDox.php',
  2094. 'PHPUnit\\Event\\Code\\TestDoxBuilder' => '/phpunit/Event/Value/Test/TestDoxBuilder.php',
  2095. 'PHPUnit\\Event\\Code\\TestMethod' => '/phpunit/Event/Value/Test/TestMethod.php',
  2096. 'PHPUnit\\Event\\Code\\TestMethodBuilder' => '/phpunit/Event/Value/Test/TestMethodBuilder.php',
  2097. 'PHPUnit\\Event\\Code\\Throwable' => '/phpunit/Event/Value/Throwable.php',
  2098. 'PHPUnit\\Event\\Code\\ThrowableBuilder' => '/phpunit/Event/Value/ThrowableBuilder.php',
  2099. 'PHPUnit\\Event\\CollectingDispatcher' => '/phpunit/Event/Dispatcher/CollectingDispatcher.php',
  2100. 'PHPUnit\\Event\\DeferringDispatcher' => '/phpunit/Event/Dispatcher/DeferringDispatcher.php',
  2101. 'PHPUnit\\Event\\DirectDispatcher' => '/phpunit/Event/Dispatcher/DirectDispatcher.php',
  2102. 'PHPUnit\\Event\\Dispatcher' => '/phpunit/Event/Dispatcher/Dispatcher.php',
  2103. 'PHPUnit\\Event\\DispatchingEmitter' => '/phpunit/Event/Emitter/DispatchingEmitter.php',
  2104. 'PHPUnit\\Event\\Emitter' => '/phpunit/Event/Emitter/Emitter.php',
  2105. 'PHPUnit\\Event\\Event' => '/phpunit/Event/Events/Event.php',
  2106. 'PHPUnit\\Event\\EventAlreadyAssignedException' => '/phpunit/Event/Exception/EventAlreadyAssignedException.php',
  2107. 'PHPUnit\\Event\\EventCollection' => '/phpunit/Event/Events/EventCollection.php',
  2108. 'PHPUnit\\Event\\EventCollectionIterator' => '/phpunit/Event/Events/EventCollectionIterator.php',
  2109. 'PHPUnit\\Event\\EventFacadeIsSealedException' => '/phpunit/Event/Exception/EventFacadeIsSealedException.php',
  2110. 'PHPUnit\\Event\\Exception' => '/phpunit/Event/Exception/Exception.php',
  2111. 'PHPUnit\\Event\\Facade' => '/phpunit/Event/Facade.php',
  2112. 'PHPUnit\\Event\\InvalidArgumentException' => '/phpunit/Event/Exception/InvalidArgumentException.php',
  2113. 'PHPUnit\\Event\\InvalidEventException' => '/phpunit/Event/Exception/InvalidEventException.php',
  2114. 'PHPUnit\\Event\\InvalidSubscriberException' => '/phpunit/Event/Exception/InvalidSubscriberException.php',
  2115. 'PHPUnit\\Event\\MapError' => '/phpunit/Event/Exception/MapError.php',
  2116. 'PHPUnit\\Event\\NoPreviousThrowableException' => '/phpunit/Event/Exception/NoPreviousThrowableException.php',
  2117. 'PHPUnit\\Event\\RuntimeException' => '/phpunit/Event/Exception/RuntimeException.php',
  2118. 'PHPUnit\\Event\\Runtime\\OperatingSystem' => '/phpunit/Event/Value/Runtime/OperatingSystem.php',
  2119. 'PHPUnit\\Event\\Runtime\\PHP' => '/phpunit/Event/Value/Runtime/PHP.php',
  2120. 'PHPUnit\\Event\\Runtime\\PHPUnit' => '/phpunit/Event/Value/Runtime/PHPUnit.php',
  2121. 'PHPUnit\\Event\\Runtime\\Runtime' => '/phpunit/Event/Value/Runtime/Runtime.php',
  2122. 'PHPUnit\\Event\\SubscribableDispatcher' => '/phpunit/Event/Dispatcher/SubscribableDispatcher.php',
  2123. 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php',
  2124. 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php',
  2125. 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php',
  2126. 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php',
  2127. 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php',
  2128. 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php',
  2129. 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php',
  2130. 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php',
  2131. 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php',
  2132. 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php',
  2133. 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php',
  2134. 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php',
  2135. 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php',
  2136. 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php',
  2137. 'PHPUnit\\Event\\Telemetry\\SystemMemoryMeter' => '/phpunit/Event/Value/Telemetry/SystemMemoryMeter.php',
  2138. 'PHPUnit\\Event\\Telemetry\\SystemStopWatch' => '/phpunit/Event/Value/Telemetry/SystemStopWatch.php',
  2139. 'PHPUnit\\Event\\Telemetry\\SystemStopWatchWithOffset' => '/phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php',
  2140. 'PHPUnit\\Event\\TestData\\DataFromDataProvider' => '/phpunit/Event/Value/Test/TestData/DataFromDataProvider.php',
  2141. 'PHPUnit\\Event\\TestData\\DataFromTestDependency' => '/phpunit/Event/Value/Test/TestData/DataFromTestDependency.php',
  2142. 'PHPUnit\\Event\\TestData\\MoreThanOneDataSetFromDataProviderException' => '/phpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php',
  2143. 'PHPUnit\\Event\\TestData\\NoDataSetFromDataProviderException' => '/phpunit/Event/Exception/NoDataSetFromDataProviderException.php',
  2144. 'PHPUnit\\Event\\TestData\\TestData' => '/phpunit/Event/Value/Test/TestData/TestData.php',
  2145. 'PHPUnit\\Event\\TestData\\TestDataCollection' => '/phpunit/Event/Value/Test/TestData/TestDataCollection.php',
  2146. 'PHPUnit\\Event\\TestData\\TestDataCollectionIterator' => '/phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.php',
  2147. 'PHPUnit\\Event\\TestRunner\\BootstrapFinished' => '/phpunit/Event/Events/TestRunner/BootstrapFinished.php',
  2148. 'PHPUnit\\Event\\TestRunner\\BootstrapFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.php',
  2149. 'PHPUnit\\Event\\TestRunner\\Configured' => '/phpunit/Event/Events/TestRunner/Configured.php',
  2150. 'PHPUnit\\Event\\TestRunner\\ConfiguredSubscriber' => '/phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php',
  2151. 'PHPUnit\\Event\\TestRunner\\DeprecationTriggered' => '/phpunit/Event/Events/TestRunner/DeprecationTriggered.php',
  2152. 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php',
  2153. 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php',
  2154. 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php',
  2155. 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php',
  2156. 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php',
  2157. 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php',
  2158. 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php',
  2159. 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php',
  2160. 'PHPUnit\\Event\\TestRunner\\ExecutionStartedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.php',
  2161. 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrapped' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrapped.php',
  2162. 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrappedSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.php',
  2163. 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPhar' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.php',
  2164. 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php',
  2165. 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php',
  2166. 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php',
  2167. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php',
  2168. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php',
  2169. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php',
  2170. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php',
  2171. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php',
  2172. 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php',
  2173. 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php',
  2174. 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php',
  2175. 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php',
  2176. 'PHPUnit\\Event\\TestRunner\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.php',
  2177. 'PHPUnit\\Event\\TestSuite\\Filtered' => '/phpunit/Event/Events/TestSuite/Filtered.php',
  2178. 'PHPUnit\\Event\\TestSuite\\FilteredSubscriber' => '/phpunit/Event/Events/TestSuite/FilteredSubscriber.php',
  2179. 'PHPUnit\\Event\\TestSuite\\Finished' => '/phpunit/Event/Events/TestSuite/Finished.php',
  2180. 'PHPUnit\\Event\\TestSuite\\FinishedSubscriber' => '/phpunit/Event/Events/TestSuite/FinishedSubscriber.php',
  2181. 'PHPUnit\\Event\\TestSuite\\Loaded' => '/phpunit/Event/Events/TestSuite/Loaded.php',
  2182. 'PHPUnit\\Event\\TestSuite\\LoadedSubscriber' => '/phpunit/Event/Events/TestSuite/LoadedSubscriber.php',
  2183. 'PHPUnit\\Event\\TestSuite\\Skipped' => '/phpunit/Event/Events/TestSuite/Skipped.php',
  2184. 'PHPUnit\\Event\\TestSuite\\SkippedSubscriber' => '/phpunit/Event/Events/TestSuite/SkippedSubscriber.php',
  2185. 'PHPUnit\\Event\\TestSuite\\Sorted' => '/phpunit/Event/Events/TestSuite/Sorted.php',
  2186. 'PHPUnit\\Event\\TestSuite\\SortedSubscriber' => '/phpunit/Event/Events/TestSuite/SortedSubscriber.php',
  2187. 'PHPUnit\\Event\\TestSuite\\Started' => '/phpunit/Event/Events/TestSuite/Started.php',
  2188. 'PHPUnit\\Event\\TestSuite\\StartedSubscriber' => '/phpunit/Event/Events/TestSuite/StartedSubscriber.php',
  2189. 'PHPUnit\\Event\\TestSuite\\TestSuite' => '/phpunit/Event/Value/TestSuite/TestSuite.php',
  2190. 'PHPUnit\\Event\\TestSuite\\TestSuiteBuilder' => '/phpunit/Event/Value/TestSuite/TestSuiteBuilder.php',
  2191. 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestClass' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php',
  2192. 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestMethodWithDataProvider' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.php',
  2193. 'PHPUnit\\Event\\TestSuite\\TestSuiteWithName' => '/phpunit/Event/Value/TestSuite/TestSuiteWithName.php',
  2194. 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.php',
  2195. 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.php',
  2196. 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php',
  2197. 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.php',
  2198. 'PHPUnit\\Event\\Test\\AfterTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php',
  2199. 'PHPUnit\\Event\\Test\\AfterTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.php',
  2200. 'PHPUnit\\Event\\Test\\AfterTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php',
  2201. 'PHPUnit\\Event\\Test\\AfterTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.php',
  2202. 'PHPUnit\\Event\\Test\\AssertionFailed' => '/phpunit/Event/Events/Test/Assertion/AssertionFailed.php',
  2203. 'PHPUnit\\Event\\Test\\AssertionFailedSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.php',
  2204. 'PHPUnit\\Event\\Test\\AssertionSucceeded' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php',
  2205. 'PHPUnit\\Event\\Test\\AssertionSucceededSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.php',
  2206. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.php',
  2207. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.php',
  2208. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.php',
  2209. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.php',
  2210. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.php',
  2211. 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.php',
  2212. 'PHPUnit\\Event\\Test\\BeforeTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.php',
  2213. 'PHPUnit\\Event\\Test\\BeforeTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.php',
  2214. 'PHPUnit\\Event\\Test\\BeforeTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.php',
  2215. 'PHPUnit\\Event\\Test\\BeforeTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.php',
  2216. 'PHPUnit\\Event\\Test\\ComparatorRegistered' => '/phpunit/Event/Events/Test/ComparatorRegistered.php',
  2217. 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php',
  2218. 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php',
  2219. 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php',
  2220. 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php',
  2221. 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php',
  2222. 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php',
  2223. 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php',
  2224. 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php',
  2225. 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php',
  2226. 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php',
  2227. 'PHPUnit\\Event\\Test\\ErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php',
  2228. 'PHPUnit\\Event\\Test\\Errored' => '/phpunit/Event/Events/Test/Outcome/Errored.php',
  2229. 'PHPUnit\\Event\\Test\\ErroredSubscriber' => '/phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php',
  2230. 'PHPUnit\\Event\\Test\\Failed' => '/phpunit/Event/Events/Test/Outcome/Failed.php',
  2231. 'PHPUnit\\Event\\Test\\FailedSubscriber' => '/phpunit/Event/Events/Test/Outcome/FailedSubscriber.php',
  2232. 'PHPUnit\\Event\\Test\\Finished' => '/phpunit/Event/Events/Test/Lifecycle/Finished.php',
  2233. 'PHPUnit\\Event\\Test\\FinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php',
  2234. 'PHPUnit\\Event\\Test\\MarkedIncomplete' => '/phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php',
  2235. 'PHPUnit\\Event\\Test\\MarkedIncompleteSubscriber' => '/phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php',
  2236. 'PHPUnit\\Event\\Test\\MockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php',
  2237. 'PHPUnit\\Event\\Test\\MockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php',
  2238. 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php',
  2239. 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php',
  2240. 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.php',
  2241. 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.php',
  2242. 'PHPUnit\\Event\\Test\\MockObjectForTraitCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php',
  2243. 'PHPUnit\\Event\\Test\\MockObjectForTraitCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.php',
  2244. 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php',
  2245. 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.php',
  2246. 'PHPUnit\\Event\\Test\\NoComparisonFailureException' => '/phpunit/Event/Exception/NoComparisonFailureException.php',
  2247. 'PHPUnit\\Event\\Test\\NoticeTriggered' => '/phpunit/Event/Events/Test/Issue/NoticeTriggered.php',
  2248. 'PHPUnit\\Event\\Test\\NoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php',
  2249. 'PHPUnit\\Event\\Test\\PartialMockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php',
  2250. 'PHPUnit\\Event\\Test\\PartialMockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.php',
  2251. 'PHPUnit\\Event\\Test\\Passed' => '/phpunit/Event/Events/Test/Outcome/Passed.php',
  2252. 'PHPUnit\\Event\\Test\\PassedSubscriber' => '/phpunit/Event/Events/Test/Outcome/PassedSubscriber.php',
  2253. 'PHPUnit\\Event\\Test\\PhpDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php',
  2254. 'PHPUnit\\Event\\Test\\PhpDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.php',
  2255. 'PHPUnit\\Event\\Test\\PhpNoticeTriggered' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php',
  2256. 'PHPUnit\\Event\\Test\\PhpNoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php',
  2257. 'PHPUnit\\Event\\Test\\PhpWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php',
  2258. 'PHPUnit\\Event\\Test\\PhpWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php',
  2259. 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.php',
  2260. 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.php',
  2261. 'PHPUnit\\Event\\Test\\PhpunitErrorTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.php',
  2262. 'PHPUnit\\Event\\Test\\PhpunitErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.php',
  2263. 'PHPUnit\\Event\\Test\\PhpunitWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php',
  2264. 'PHPUnit\\Event\\Test\\PhpunitWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.php',
  2265. 'PHPUnit\\Event\\Test\\PostConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalled.php',
  2266. 'PHPUnit\\Event\\Test\\PostConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php',
  2267. 'PHPUnit\\Event\\Test\\PostConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinished.php',
  2268. 'PHPUnit\\Event\\Test\\PostConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.php',
  2269. 'PHPUnit\\Event\\Test\\PreConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php',
  2270. 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php',
  2271. 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php',
  2272. 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php',
  2273. 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php',
  2274. 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php',
  2275. 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php',
  2276. 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php',
  2277. 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php',
  2278. 'PHPUnit\\Event\\Test\\PreparedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php',
  2279. 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutput' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutput.php',
  2280. 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutputSubscriber' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.php',
  2281. 'PHPUnit\\Event\\Test\\Skipped' => '/phpunit/Event/Events/Test/Outcome/Skipped.php',
  2282. 'PHPUnit\\Event\\Test\\SkippedSubscriber' => '/phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php',
  2283. 'PHPUnit\\Event\\Test\\TestProxyCreated' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreated.php',
  2284. 'PHPUnit\\Event\\Test\\TestProxyCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php',
  2285. 'PHPUnit\\Event\\Test\\TestStubCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreated.php',
  2286. 'PHPUnit\\Event\\Test\\TestStubCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php',
  2287. 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.php',
  2288. 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.php',
  2289. 'PHPUnit\\Event\\Test\\WarningTriggered' => '/phpunit/Event/Events/Test/Issue/WarningTriggered.php',
  2290. 'PHPUnit\\Event\\Test\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php',
  2291. 'PHPUnit\\Event\\Tracer\\Tracer' => '/phpunit/Event/Tracer.php',
  2292. 'PHPUnit\\Event\\TypeMap' => '/phpunit/Event/TypeMap.php',
  2293. 'PHPUnit\\Event\\UnknownEventException' => '/phpunit/Event/Exception/UnknownEventException.php',
  2294. 'PHPUnit\\Event\\UnknownEventTypeException' => '/phpunit/Event/Exception/UnknownEventTypeException.php',
  2295. 'PHPUnit\\Event\\UnknownSubscriberException' => '/phpunit/Event/Exception/UnknownSubscriberException.php',
  2296. 'PHPUnit\\Event\\UnknownSubscriberTypeException' => '/phpunit/Event/Exception/UnknownSubscriberTypeException.php',
  2297. 'PHPUnit\\Exception' => '/phpunit/Exception.php',
  2298. 'PHPUnit\\Framework\\ActualValueIsNotAnObjectException' => '/phpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php',
  2299. 'PHPUnit\\Framework\\Assert' => '/phpunit/Framework/Assert.php',
  2300. 'PHPUnit\\Framework\\AssertionFailedError' => '/phpunit/Framework/Exception/AssertionFailedError.php',
  2301. 'PHPUnit\\Framework\\Attributes\\After' => '/phpunit/Framework/Attributes/After.php',
  2302. 'PHPUnit\\Framework\\Attributes\\AfterClass' => '/phpunit/Framework/Attributes/AfterClass.php',
  2303. 'PHPUnit\\Framework\\Attributes\\BackupGlobals' => '/phpunit/Framework/Attributes/BackupGlobals.php',
  2304. 'PHPUnit\\Framework\\Attributes\\BackupStaticProperties' => '/phpunit/Framework/Attributes/BackupStaticProperties.php',
  2305. 'PHPUnit\\Framework\\Attributes\\Before' => '/phpunit/Framework/Attributes/Before.php',
  2306. 'PHPUnit\\Framework\\Attributes\\BeforeClass' => '/phpunit/Framework/Attributes/BeforeClass.php',
  2307. 'PHPUnit\\Framework\\Attributes\\CodeCoverageIgnore' => '/phpunit/Framework/Attributes/CodeCoverageIgnore.php',
  2308. 'PHPUnit\\Framework\\Attributes\\CoversClass' => '/phpunit/Framework/Attributes/CoversClass.php',
  2309. 'PHPUnit\\Framework\\Attributes\\CoversFunction' => '/phpunit/Framework/Attributes/CoversFunction.php',
  2310. 'PHPUnit\\Framework\\Attributes\\CoversNothing' => '/phpunit/Framework/Attributes/CoversNothing.php',
  2311. 'PHPUnit\\Framework\\Attributes\\DataProvider' => '/phpunit/Framework/Attributes/DataProvider.php',
  2312. 'PHPUnit\\Framework\\Attributes\\DataProviderExternal' => '/phpunit/Framework/Attributes/DataProviderExternal.php',
  2313. 'PHPUnit\\Framework\\Attributes\\Depends' => '/phpunit/Framework/Attributes/Depends.php',
  2314. 'PHPUnit\\Framework\\Attributes\\DependsExternal' => '/phpunit/Framework/Attributes/DependsExternal.php',
  2315. 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingDeepClone' => '/phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php',
  2316. 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingShallowClone' => '/phpunit/Framework/Attributes/DependsExternalUsingShallowClone.php',
  2317. 'PHPUnit\\Framework\\Attributes\\DependsOnClass' => '/phpunit/Framework/Attributes/DependsOnClass.php',
  2318. 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingDeepClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php',
  2319. 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingShallowClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php',
  2320. 'PHPUnit\\Framework\\Attributes\\DependsUsingDeepClone' => '/phpunit/Framework/Attributes/DependsUsingDeepClone.php',
  2321. 'PHPUnit\\Framework\\Attributes\\DependsUsingShallowClone' => '/phpunit/Framework/Attributes/DependsUsingShallowClone.php',
  2322. 'PHPUnit\\Framework\\Attributes\\DoesNotPerformAssertions' => '/phpunit/Framework/Attributes/DoesNotPerformAssertions.php',
  2323. 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php',
  2324. 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php',
  2325. 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php',
  2326. 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php',
  2327. 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php',
  2328. 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php',
  2329. 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php',
  2330. 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php',
  2331. 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php',
  2332. 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php',
  2333. 'PHPUnit\\Framework\\Attributes\\PreCondition' => '/phpunit/Framework/Attributes/PreCondition.php',
  2334. 'PHPUnit\\Framework\\Attributes\\PreserveGlobalState' => '/phpunit/Framework/Attributes/PreserveGlobalState.php',
  2335. 'PHPUnit\\Framework\\Attributes\\RequiresFunction' => '/phpunit/Framework/Attributes/RequiresFunction.php',
  2336. 'PHPUnit\\Framework\\Attributes\\RequiresMethod' => '/phpunit/Framework/Attributes/RequiresMethod.php',
  2337. 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem' => '/phpunit/Framework/Attributes/RequiresOperatingSystem.php',
  2338. 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily' => '/phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php',
  2339. 'PHPUnit\\Framework\\Attributes\\RequiresPhp' => '/phpunit/Framework/Attributes/RequiresPhp.php',
  2340. 'PHPUnit\\Framework\\Attributes\\RequiresPhpExtension' => '/phpunit/Framework/Attributes/RequiresPhpExtension.php',
  2341. 'PHPUnit\\Framework\\Attributes\\RequiresPhpunit' => '/phpunit/Framework/Attributes/RequiresPhpunit.php',
  2342. 'PHPUnit\\Framework\\Attributes\\RequiresSetting' => '/phpunit/Framework/Attributes/RequiresSetting.php',
  2343. 'PHPUnit\\Framework\\Attributes\\RunClassInSeparateProcess' => '/phpunit/Framework/Attributes/RunClassInSeparateProcess.php',
  2344. 'PHPUnit\\Framework\\Attributes\\RunInSeparateProcess' => '/phpunit/Framework/Attributes/RunInSeparateProcess.php',
  2345. 'PHPUnit\\Framework\\Attributes\\RunTestsInSeparateProcesses' => '/phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php',
  2346. 'PHPUnit\\Framework\\Attributes\\Small' => '/phpunit/Framework/Attributes/Small.php',
  2347. 'PHPUnit\\Framework\\Attributes\\Test' => '/phpunit/Framework/Attributes/Test.php',
  2348. 'PHPUnit\\Framework\\Attributes\\TestDox' => '/phpunit/Framework/Attributes/TestDox.php',
  2349. 'PHPUnit\\Framework\\Attributes\\TestWith' => '/phpunit/Framework/Attributes/TestWith.php',
  2350. 'PHPUnit\\Framework\\Attributes\\TestWithJson' => '/phpunit/Framework/Attributes/TestWithJson.php',
  2351. 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php',
  2352. 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php',
  2353. 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php',
  2354. 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php',
  2355. 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php',
  2356. 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php',
  2357. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php',
  2358. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareExactlyOneParameterException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php',
  2359. 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.php',
  2360. 'PHPUnit\\Framework\\ComparisonMethodDoesNotExistException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php',
  2361. 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => '/phpunit/Framework/Constraint/Traversable/ArrayHasKey.php',
  2362. 'PHPUnit\\Framework\\Constraint\\BinaryOperator' => '/phpunit/Framework/Constraint/Operator/BinaryOperator.php',
  2363. 'PHPUnit\\Framework\\Constraint\\Callback' => '/phpunit/Framework/Constraint/Callback.php',
  2364. 'PHPUnit\\Framework\\Constraint\\Constraint' => '/phpunit/Framework/Constraint/Constraint.php',
  2365. 'PHPUnit\\Framework\\Constraint\\Count' => '/phpunit/Framework/Constraint/Cardinality/Count.php',
  2366. 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => '/phpunit/Framework/Constraint/Filesystem/DirectoryExists.php',
  2367. 'PHPUnit\\Framework\\Constraint\\Exception' => '/phpunit/Framework/Constraint/Exception/Exception.php',
  2368. 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => '/phpunit/Framework/Constraint/Exception/ExceptionCode.php',
  2369. 'PHPUnit\\Framework\\Constraint\\ExceptionMessageIsOrContains' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php',
  2370. 'PHPUnit\\Framework\\Constraint\\ExceptionMessageMatchesRegularExpression' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php',
  2371. 'PHPUnit\\Framework\\Constraint\\FileExists' => '/phpunit/Framework/Constraint/Filesystem/FileExists.php',
  2372. 'PHPUnit\\Framework\\Constraint\\GreaterThan' => '/phpunit/Framework/Constraint/Cardinality/GreaterThan.php',
  2373. 'PHPUnit\\Framework\\Constraint\\IsAnything' => '/phpunit/Framework/Constraint/IsAnything.php',
  2374. 'PHPUnit\\Framework\\Constraint\\IsEmpty' => '/phpunit/Framework/Constraint/Cardinality/IsEmpty.php',
  2375. 'PHPUnit\\Framework\\Constraint\\IsEqual' => '/phpunit/Framework/Constraint/Equality/IsEqual.php',
  2376. 'PHPUnit\\Framework\\Constraint\\IsEqualCanonicalizing' => '/phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php',
  2377. 'PHPUnit\\Framework\\Constraint\\IsEqualIgnoringCase' => '/phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php',
  2378. 'PHPUnit\\Framework\\Constraint\\IsEqualWithDelta' => '/phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php',
  2379. 'PHPUnit\\Framework\\Constraint\\IsFalse' => '/phpunit/Framework/Constraint/Boolean/IsFalse.php',
  2380. 'PHPUnit\\Framework\\Constraint\\IsFinite' => '/phpunit/Framework/Constraint/Math/IsFinite.php',
  2381. 'PHPUnit\\Framework\\Constraint\\IsIdentical' => '/phpunit/Framework/Constraint/IsIdentical.php',
  2382. 'PHPUnit\\Framework\\Constraint\\IsInfinite' => '/phpunit/Framework/Constraint/Math/IsInfinite.php',
  2383. 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => '/phpunit/Framework/Constraint/Type/IsInstanceOf.php',
  2384. 'PHPUnit\\Framework\\Constraint\\IsJson' => '/phpunit/Framework/Constraint/String/IsJson.php',
  2385. 'PHPUnit\\Framework\\Constraint\\IsList' => '/phpunit/Framework/Constraint/Traversable/IsList.php',
  2386. 'PHPUnit\\Framework\\Constraint\\IsNan' => '/phpunit/Framework/Constraint/Math/IsNan.php',
  2387. 'PHPUnit\\Framework\\Constraint\\IsNull' => '/phpunit/Framework/Constraint/Type/IsNull.php',
  2388. 'PHPUnit\\Framework\\Constraint\\IsReadable' => '/phpunit/Framework/Constraint/Filesystem/IsReadable.php',
  2389. 'PHPUnit\\Framework\\Constraint\\IsTrue' => '/phpunit/Framework/Constraint/Boolean/IsTrue.php',
  2390. 'PHPUnit\\Framework\\Constraint\\IsType' => '/phpunit/Framework/Constraint/Type/IsType.php',
  2391. 'PHPUnit\\Framework\\Constraint\\IsWritable' => '/phpunit/Framework/Constraint/Filesystem/IsWritable.php',
  2392. 'PHPUnit\\Framework\\Constraint\\JsonMatches' => '/phpunit/Framework/Constraint/JsonMatches.php',
  2393. 'PHPUnit\\Framework\\Constraint\\LessThan' => '/phpunit/Framework/Constraint/Cardinality/LessThan.php',
  2394. 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => '/phpunit/Framework/Constraint/Operator/LogicalAnd.php',
  2395. 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php',
  2396. 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php',
  2397. 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php',
  2398. 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php',
  2399. 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php',
  2400. 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php',
  2401. 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php',
  2402. 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php',
  2403. 'PHPUnit\\Framework\\Constraint\\StringContains' => '/phpunit/Framework/Constraint/String/StringContains.php',
  2404. 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => '/phpunit/Framework/Constraint/String/StringEndsWith.php',
  2405. 'PHPUnit\\Framework\\Constraint\\StringEqualsStringIgnoringLineEndings' => '/phpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php',
  2406. 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => '/phpunit/Framework/Constraint/String/StringMatchesFormatDescription.php',
  2407. 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => '/phpunit/Framework/Constraint/String/StringStartsWith.php',
  2408. 'PHPUnit\\Framework\\Constraint\\TraversableContains' => '/phpunit/Framework/Constraint/Traversable/TraversableContains.php',
  2409. 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php',
  2410. 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.php',
  2411. 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php',
  2412. 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php',
  2413. 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php',
  2414. 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php',
  2415. 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php',
  2416. 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php',
  2417. 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php',
  2418. 'PHPUnit\\Framework\\GeneratorNotSupportedException' => '/phpunit/Framework/Exception/GeneratorNotSupportedException.php',
  2419. 'PHPUnit\\Framework\\IncompleteTest' => '/phpunit/Framework/Exception/Incomplete/IncompleteTest.php',
  2420. 'PHPUnit\\Framework\\IncompleteTestError' => '/phpunit/Framework/Exception/Incomplete/IncompleteTestError.php',
  2421. 'PHPUnit\\Framework\\InvalidArgumentException' => '/phpunit/Framework/Exception/InvalidArgumentException.php',
  2422. 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php',
  2423. 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php',
  2424. 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php',
  2425. 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php',
  2426. 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php',
  2427. 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php',
  2428. 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php',
  2429. 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php',
  2430. 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php',
  2431. 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php',
  2432. 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php',
  2433. 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php',
  2434. 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php',
  2435. 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php',
  2436. 'PHPUnit\\Framework\\MockObject\\Generator\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.php',
  2437. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php',
  2438. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php',
  2439. 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php',
  2440. 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php',
  2441. 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php',
  2442. 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php',
  2443. 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php',
  2444. 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php',
  2445. 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php',
  2446. 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php',
  2447. 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php',
  2448. 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php',
  2449. 'PHPUnit\\Framework\\MockObject\\Generator\\NameAlreadyInUseException' => '/phpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.php',
  2450. 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php',
  2451. 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php',
  2452. 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php',
  2453. 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php',
  2454. 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php',
  2455. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php',
  2456. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php',
  2457. 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php',
  2458. 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php',
  2459. 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php',
  2460. 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php',
  2461. 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php',
  2462. 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php',
  2463. 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php',
  2464. 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php',
  2465. 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php',
  2466. 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php',
  2467. 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php',
  2468. 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php',
  2469. 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php',
  2470. 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php',
  2471. 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php',
  2472. 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php',
  2473. 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php',
  2474. 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php',
  2475. 'PHPUnit\\Framework\\MockObject\\NoMoreReturnValuesConfiguredException' => '/phpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php',
  2476. 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php',
  2477. 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php',
  2478. 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php',
  2479. 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php',
  2480. 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php',
  2481. 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php',
  2482. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php',
  2483. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php',
  2484. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php',
  2485. 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php',
  2486. 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php',
  2487. 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php',
  2488. 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php',
  2489. 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php',
  2490. 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php',
  2491. 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php',
  2492. 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php',
  2493. 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php',
  2494. 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php',
  2495. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php',
  2496. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php',
  2497. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php',
  2498. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php',
  2499. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php',
  2500. 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php',
  2501. 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php',
  2502. 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php',
  2503. 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php',
  2504. 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php',
  2505. 'PHPUnit\\Framework\\Reorderable' => '/phpunit/Framework/Reorderable.php',
  2506. 'PHPUnit\\Framework\\SelfDescribing' => '/phpunit/Framework/SelfDescribing.php',
  2507. 'PHPUnit\\Framework\\SkippedTest' => '/phpunit/Framework/Exception/Skipped/SkippedTest.php',
  2508. 'PHPUnit\\Framework\\SkippedTestSuiteError' => '/phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.php',
  2509. 'PHPUnit\\Framework\\SkippedWithMessageException' => '/phpunit/Framework/Exception/Skipped/SkippedWithMessageException.php',
  2510. 'PHPUnit\\Framework\\Test' => '/phpunit/Framework/Test.php',
  2511. 'PHPUnit\\Framework\\TestBuilder' => '/phpunit/Framework/TestBuilder.php',
  2512. 'PHPUnit\\Framework\\TestCase' => '/phpunit/Framework/TestCase.php',
  2513. 'PHPUnit\\Framework\\TestRunner' => '/phpunit/Framework/TestRunner.php',
  2514. 'PHPUnit\\Framework\\TestSize\\Known' => '/phpunit/Framework/TestSize/Known.php',
  2515. 'PHPUnit\\Framework\\TestSize\\Large' => '/phpunit/Framework/TestSize/Large.php',
  2516. 'PHPUnit\\Framework\\TestSize\\Medium' => '/phpunit/Framework/TestSize/Medium.php',
  2517. 'PHPUnit\\Framework\\TestSize\\Small' => '/phpunit/Framework/TestSize/Small.php',
  2518. 'PHPUnit\\Framework\\TestSize\\TestSize' => '/phpunit/Framework/TestSize/TestSize.php',
  2519. 'PHPUnit\\Framework\\TestSize\\Unknown' => '/phpunit/Framework/TestSize/Unknown.php',
  2520. 'PHPUnit\\Framework\\TestStatus\\Deprecation' => '/phpunit/Framework/TestStatus/Deprecation.php',
  2521. 'PHPUnit\\Framework\\TestStatus\\Error' => '/phpunit/Framework/TestStatus/Error.php',
  2522. 'PHPUnit\\Framework\\TestStatus\\Failure' => '/phpunit/Framework/TestStatus/Failure.php',
  2523. 'PHPUnit\\Framework\\TestStatus\\Incomplete' => '/phpunit/Framework/TestStatus/Incomplete.php',
  2524. 'PHPUnit\\Framework\\TestStatus\\Known' => '/phpunit/Framework/TestStatus/Known.php',
  2525. 'PHPUnit\\Framework\\TestStatus\\Notice' => '/phpunit/Framework/TestStatus/Notice.php',
  2526. 'PHPUnit\\Framework\\TestStatus\\Risky' => '/phpunit/Framework/TestStatus/Risky.php',
  2527. 'PHPUnit\\Framework\\TestStatus\\Skipped' => '/phpunit/Framework/TestStatus/Skipped.php',
  2528. 'PHPUnit\\Framework\\TestStatus\\Success' => '/phpunit/Framework/TestStatus/Success.php',
  2529. 'PHPUnit\\Framework\\TestStatus\\TestStatus' => '/phpunit/Framework/TestStatus/TestStatus.php',
  2530. 'PHPUnit\\Framework\\TestStatus\\Unknown' => '/phpunit/Framework/TestStatus/Unknown.php',
  2531. 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php',
  2532. 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php',
  2533. 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php',
  2534. 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php',
  2535. 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php',
  2536. 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php',
  2537. 'PHPUnit\\Logging\\JUnit\\JunitXmlLogger' => '/phpunit/Logging/JUnit/JunitXmlLogger.php',
  2538. 'PHPUnit\\Logging\\JUnit\\Subscriber' => '/phpunit/Logging/JUnit/Subscriber/Subscriber.php',
  2539. 'PHPUnit\\Logging\\JUnit\\TestErroredSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.php',
  2540. 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php',
  2541. 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php',
  2542. 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php',
  2543. 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php',
  2544. 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php',
  2545. 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php',
  2546. 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
  2547. 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php',
  2548. 'PHPUnit\\Logging\\JUnit\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php',
  2549. 'PHPUnit\\Logging\\JUnit\\TestSuiteStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php',
  2550. 'PHPUnit\\Logging\\TeamCity\\Subscriber' => '/phpunit/Logging/TeamCity/Subscriber/Subscriber.php',
  2551. 'PHPUnit\\Logging\\TeamCity\\TeamCityLogger' => '/phpunit/Logging/TeamCity/TeamCityLogger.php',
  2552. 'PHPUnit\\Logging\\TeamCity\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php',
  2553. 'PHPUnit\\Logging\\TeamCity\\TestErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.php',
  2554. 'PHPUnit\\Logging\\TeamCity\\TestFailedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php',
  2555. 'PHPUnit\\Logging\\TeamCity\\TestFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php',
  2556. 'PHPUnit\\Logging\\TeamCity\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php',
  2557. 'PHPUnit\\Logging\\TeamCity\\TestPreparedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php',
  2558. 'PHPUnit\\Logging\\TeamCity\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
  2559. 'PHPUnit\\Logging\\TeamCity\\TestSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.php',
  2560. 'PHPUnit\\Logging\\TeamCity\\TestSuiteBeforeFirstTestMethodErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.php',
  2561. 'PHPUnit\\Logging\\TeamCity\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php',
  2562. 'PHPUnit\\Logging\\TeamCity\\TestSuiteSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.php',
  2563. 'PHPUnit\\Logging\\TeamCity\\TestSuiteStartedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php',
  2564. 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php',
  2565. 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php',
  2566. 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php',
  2567. 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php',
  2568. 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
  2569. 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php',
  2570. 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php',
  2571. 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php',
  2572. 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
  2573. 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php',
  2574. 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php',
  2575. 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php',
  2576. 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php',
  2577. 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php',
  2578. 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php',
  2579. 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php',
  2580. 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
  2581. 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
  2582. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  2583. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  2584. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  2585. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  2586. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
  2587. 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  2588. 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
  2589. 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php',
  2590. 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php',
  2591. 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php',
  2592. 'PHPUnit\\Metadata\\Annotation\\Parser\\Registry' => '/phpunit/Metadata/Parser/Annotation/Registry.php',
  2593. 'PHPUnit\\Metadata\\AnnotationsAreNotSupportedForInternalClassesException' => '/phpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php',
  2594. 'PHPUnit\\Metadata\\Api\\CodeCoverage' => '/phpunit/Metadata/Api/CodeCoverage.php',
  2595. 'PHPUnit\\Metadata\\Api\\DataProvider' => '/phpunit/Metadata/Api/DataProvider.php',
  2596. 'PHPUnit\\Metadata\\Api\\Dependencies' => '/phpunit/Metadata/Api/Dependencies.php',
  2597. 'PHPUnit\\Metadata\\Api\\Groups' => '/phpunit/Metadata/Api/Groups.php',
  2598. 'PHPUnit\\Metadata\\Api\\HookMethods' => '/phpunit/Metadata/Api/HookMethods.php',
  2599. 'PHPUnit\\Metadata\\Api\\Requirements' => '/phpunit/Metadata/Api/Requirements.php',
  2600. 'PHPUnit\\Metadata\\BackupGlobals' => '/phpunit/Metadata/BackupGlobals.php',
  2601. 'PHPUnit\\Metadata\\BackupStaticProperties' => '/phpunit/Metadata/BackupStaticProperties.php',
  2602. 'PHPUnit\\Metadata\\Before' => '/phpunit/Metadata/Before.php',
  2603. 'PHPUnit\\Metadata\\BeforeClass' => '/phpunit/Metadata/BeforeClass.php',
  2604. 'PHPUnit\\Metadata\\Covers' => '/phpunit/Metadata/Covers.php',
  2605. 'PHPUnit\\Metadata\\CoversClass' => '/phpunit/Metadata/CoversClass.php',
  2606. 'PHPUnit\\Metadata\\CoversDefaultClass' => '/phpunit/Metadata/CoversDefaultClass.php',
  2607. 'PHPUnit\\Metadata\\CoversFunction' => '/phpunit/Metadata/CoversFunction.php',
  2608. 'PHPUnit\\Metadata\\CoversNothing' => '/phpunit/Metadata/CoversNothing.php',
  2609. 'PHPUnit\\Metadata\\DataProvider' => '/phpunit/Metadata/DataProvider.php',
  2610. 'PHPUnit\\Metadata\\DependsOnClass' => '/phpunit/Metadata/DependsOnClass.php',
  2611. 'PHPUnit\\Metadata\\DependsOnMethod' => '/phpunit/Metadata/DependsOnMethod.php',
  2612. 'PHPUnit\\Metadata\\DoesNotPerformAssertions' => '/phpunit/Metadata/DoesNotPerformAssertions.php',
  2613. 'PHPUnit\\Metadata\\Exception' => '/phpunit/Metadata/Exception/Exception.php',
  2614. 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php',
  2615. 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php',
  2616. 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php',
  2617. 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php',
  2618. 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php',
  2619. 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php',
  2620. 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php',
  2621. 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php',
  2622. 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php',
  2623. 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php',
  2624. 'PHPUnit\\Metadata\\MetadataCollectionIterator' => '/phpunit/Metadata/MetadataCollectionIterator.php',
  2625. 'PHPUnit\\Metadata\\NoVersionRequirementException' => '/phpunit/Metadata/Exception/NoVersionRequirementException.php',
  2626. 'PHPUnit\\Metadata\\Parser\\AnnotationParser' => '/phpunit/Metadata/Parser/AnnotationParser.php',
  2627. 'PHPUnit\\Metadata\\Parser\\AttributeParser' => '/phpunit/Metadata/Parser/AttributeParser.php',
  2628. 'PHPUnit\\Metadata\\Parser\\CachingParser' => '/phpunit/Metadata/Parser/CachingParser.php',
  2629. 'PHPUnit\\Metadata\\Parser\\Parser' => '/phpunit/Metadata/Parser/Parser.php',
  2630. 'PHPUnit\\Metadata\\Parser\\ParserChain' => '/phpunit/Metadata/Parser/ParserChain.php',
  2631. 'PHPUnit\\Metadata\\Parser\\Registry' => '/phpunit/Metadata/Parser/Registry.php',
  2632. 'PHPUnit\\Metadata\\PostCondition' => '/phpunit/Metadata/PostCondition.php',
  2633. 'PHPUnit\\Metadata\\PreCondition' => '/phpunit/Metadata/PreCondition.php',
  2634. 'PHPUnit\\Metadata\\PreserveGlobalState' => '/phpunit/Metadata/PreserveGlobalState.php',
  2635. 'PHPUnit\\Metadata\\ReflectionException' => '/phpunit/Metadata/Exception/ReflectionException.php',
  2636. 'PHPUnit\\Metadata\\RequiresFunction' => '/phpunit/Metadata/RequiresFunction.php',
  2637. 'PHPUnit\\Metadata\\RequiresMethod' => '/phpunit/Metadata/RequiresMethod.php',
  2638. 'PHPUnit\\Metadata\\RequiresOperatingSystem' => '/phpunit/Metadata/RequiresOperatingSystem.php',
  2639. 'PHPUnit\\Metadata\\RequiresOperatingSystemFamily' => '/phpunit/Metadata/RequiresOperatingSystemFamily.php',
  2640. 'PHPUnit\\Metadata\\RequiresPhp' => '/phpunit/Metadata/RequiresPhp.php',
  2641. 'PHPUnit\\Metadata\\RequiresPhpExtension' => '/phpunit/Metadata/RequiresPhpExtension.php',
  2642. 'PHPUnit\\Metadata\\RequiresPhpunit' => '/phpunit/Metadata/RequiresPhpunit.php',
  2643. 'PHPUnit\\Metadata\\RequiresSetting' => '/phpunit/Metadata/RequiresSetting.php',
  2644. 'PHPUnit\\Metadata\\RunClassInSeparateProcess' => '/phpunit/Metadata/RunClassInSeparateProcess.php',
  2645. 'PHPUnit\\Metadata\\RunInSeparateProcess' => '/phpunit/Metadata/RunInSeparateProcess.php',
  2646. 'PHPUnit\\Metadata\\RunTestsInSeparateProcesses' => '/phpunit/Metadata/RunTestsInSeparateProcesses.php',
  2647. 'PHPUnit\\Metadata\\Test' => '/phpunit/Metadata/Test.php',
  2648. 'PHPUnit\\Metadata\\TestDox' => '/phpunit/Metadata/TestDox.php',
  2649. 'PHPUnit\\Metadata\\TestWith' => '/phpunit/Metadata/TestWith.php',
  2650. 'PHPUnit\\Metadata\\Uses' => '/phpunit/Metadata/Uses.php',
  2651. 'PHPUnit\\Metadata\\UsesClass' => '/phpunit/Metadata/UsesClass.php',
  2652. 'PHPUnit\\Metadata\\UsesDefaultClass' => '/phpunit/Metadata/UsesDefaultClass.php',
  2653. 'PHPUnit\\Metadata\\UsesFunction' => '/phpunit/Metadata/UsesFunction.php',
  2654. 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php',
  2655. 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php',
  2656. 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php',
  2657. 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php',
  2658. 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php',
  2659. 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php',
  2660. 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php',
  2661. 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php',
  2662. 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php',
  2663. 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php',
  2664. 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php',
  2665. 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php',
  2666. 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php',
  2667. 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php',
  2668. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  2669. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  2670. 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  2671. 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php',
  2672. 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php',
  2673. 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php',
  2674. 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php',
  2675. 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php',
  2676. 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php',
  2677. 'PHPUnit\\Runner\\DirectoryDoesNotExistException' => '/phpunit/Runner/Exception/DirectoryDoesNotExistException.php',
  2678. 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php',
  2679. 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php',
  2680. 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php',
  2681. 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php',
  2682. 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php',
  2683. 'PHPUnit\\Runner\\Extension\\Facade' => '/phpunit/Runner/Extension/Facade.php',
  2684. 'PHPUnit\\Runner\\Extension\\ParameterCollection' => '/phpunit/Runner/Extension/ParameterCollection.php',
  2685. 'PHPUnit\\Runner\\Extension\\PharLoader' => '/phpunit/Runner/Extension/PharLoader.php',
  2686. 'PHPUnit\\Runner\\FileDoesNotExistException' => '/phpunit/Runner/Exception/FileDoesNotExistException.php',
  2687. 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => '/phpunit/Runner/Filter/ExcludeGroupFilterIterator.php',
  2688. 'PHPUnit\\Runner\\Filter\\Factory' => '/phpunit/Runner/Filter/Factory.php',
  2689. 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php',
  2690. 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php',
  2691. 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php',
  2692. 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php',
  2693. 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php',
  2694. 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php',
  2695. 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php',
  2696. 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php',
  2697. 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php',
  2698. 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php',
  2699. 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php',
  2700. 'PHPUnit\\Runner\\ParameterDoesNotExistException' => '/phpunit/Runner/Exception/ParameterDoesNotExistException.php',
  2701. 'PHPUnit\\Runner\\PhptExternalFileCannotBeLoadedException' => '/phpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.php',
  2702. 'PHPUnit\\Runner\\PhptTestCase' => '/phpunit/Runner/PhptTestCase.php',
  2703. 'PHPUnit\\Runner\\ResultCache\\DefaultResultCache' => '/phpunit/Runner/ResultCache/DefaultResultCache.php',
  2704. 'PHPUnit\\Runner\\ResultCache\\NullResultCache' => '/phpunit/Runner/ResultCache/NullResultCache.php',
  2705. 'PHPUnit\\Runner\\ResultCache\\ResultCache' => '/phpunit/Runner/ResultCache/ResultCache.php',
  2706. 'PHPUnit\\Runner\\ResultCache\\ResultCacheHandler' => '/phpunit/Runner/ResultCache/ResultCacheHandler.php',
  2707. 'PHPUnit\\Runner\\ResultCache\\Subscriber' => '/phpunit/Runner/ResultCache/Subscriber/Subscriber.php',
  2708. 'PHPUnit\\Runner\\ResultCache\\TestConsideredRiskySubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.php',
  2709. 'PHPUnit\\Runner\\ResultCache\\TestErroredSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php',
  2710. 'PHPUnit\\Runner\\ResultCache\\TestFailedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php',
  2711. 'PHPUnit\\Runner\\ResultCache\\TestFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.php',
  2712. 'PHPUnit\\Runner\\ResultCache\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.php',
  2713. 'PHPUnit\\Runner\\ResultCache\\TestPreparedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php',
  2714. 'PHPUnit\\Runner\\ResultCache\\TestSkippedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.php',
  2715. 'PHPUnit\\Runner\\ResultCache\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php',
  2716. 'PHPUnit\\Runner\\ResultCache\\TestSuiteStartedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php',
  2717. 'PHPUnit\\Runner\\TestSuiteLoader' => '/phpunit/Runner/TestSuiteLoader.php',
  2718. 'PHPUnit\\Runner\\TestSuiteSorter' => '/phpunit/Runner/TestSuiteSorter.php',
  2719. 'PHPUnit\\Runner\\UnsupportedPhptSectionException' => '/phpunit/Runner/Exception/UnsupportedPhptSectionException.php',
  2720. 'PHPUnit\\Runner\\Version' => '/phpunit/Runner/Version.php',
  2721. 'PHPUnit\\TestRunner\\TestResult\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
  2722. 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php',
  2723. 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php',
  2724. 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php',
  2725. 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php',
  2726. 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php',
  2727. 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php',
  2728. 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
  2729. 'PHPUnit\\TestRunner\\TestResult\\TestErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php',
  2730. 'PHPUnit\\TestRunner\\TestResult\\TestFailedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php',
  2731. 'PHPUnit\\TestRunner\\TestResult\\TestFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php',
  2732. 'PHPUnit\\TestRunner\\TestResult\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
  2733. 'PHPUnit\\TestRunner\\TestResult\\TestPreparedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php',
  2734. 'PHPUnit\\TestRunner\\TestResult\\TestResult' => '/phpunit/Runner/TestResult/TestResult.php',
  2735. 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php',
  2736. 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.php',
  2737. 'PHPUnit\\TestRunner\\TestResult\\TestSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php',
  2738. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php',
  2739. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php',
  2740. 'PHPUnit\\TestRunner\\TestResult\\TestSuiteStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php',
  2741. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
  2742. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.php',
  2743. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
  2744. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  2745. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  2746. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  2747. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  2748. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
  2749. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  2750. 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
  2751. 'PHPUnit\\TextUI\\Application' => '/phpunit/TextUI/Application.php',
  2752. 'PHPUnit\\TextUI\\CannotOpenSocketException' => '/phpunit/TextUI/Exception/CannotOpenSocketException.php',
  2753. 'PHPUnit\\TextUI\\CliArguments\\Builder' => '/phpunit/TextUI/Configuration/Cli/Builder.php',
  2754. 'PHPUnit\\TextUI\\CliArguments\\Configuration' => '/phpunit/TextUI/Configuration/Cli/Configuration.php',
  2755. 'PHPUnit\\TextUI\\CliArguments\\Exception' => '/phpunit/TextUI/Configuration/Cli/Exception.php',
  2756. 'PHPUnit\\TextUI\\CliArguments\\XmlConfigurationFileFinder' => '/phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.php',
  2757. 'PHPUnit\\TextUI\\Command\\AtLeastVersionCommand' => '/phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php',
  2758. 'PHPUnit\\TextUI\\Command\\Command' => '/phpunit/TextUI/Command/Command.php',
  2759. 'PHPUnit\\TextUI\\Command\\GenerateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php',
  2760. 'PHPUnit\\TextUI\\Command\\ListGroupsCommand' => '/phpunit/TextUI/Command/Commands/ListGroupsCommand.php',
  2761. 'PHPUnit\\TextUI\\Command\\ListTestSuitesCommand' => '/phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php',
  2762. 'PHPUnit\\TextUI\\Command\\ListTestsAsTextCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.php',
  2763. 'PHPUnit\\TextUI\\Command\\ListTestsAsXmlCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php',
  2764. 'PHPUnit\\TextUI\\Command\\MigrateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php',
  2765. 'PHPUnit\\TextUI\\Command\\Result' => '/phpunit/TextUI/Command/Result.php',
  2766. 'PHPUnit\\TextUI\\Command\\ShowHelpCommand' => '/phpunit/TextUI/Command/Commands/ShowHelpCommand.php',
  2767. 'PHPUnit\\TextUI\\Command\\ShowVersionCommand' => '/phpunit/TextUI/Command/Commands/ShowVersionCommand.php',
  2768. 'PHPUnit\\TextUI\\Command\\VersionCheckCommand' => '/phpunit/TextUI/Command/Commands/VersionCheckCommand.php',
  2769. 'PHPUnit\\TextUI\\Command\\WarmCodeCoverageCacheCommand' => '/phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
  2770. 'PHPUnit\\TextUI\\Configuration\\Builder' => '/phpunit/TextUI/Configuration/Builder.php',
  2771. 'PHPUnit\\TextUI\\Configuration\\CodeCoverageFilterRegistry' => '/phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php',
  2772. 'PHPUnit\\TextUI\\Configuration\\CodeCoverageReportNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php',
  2773. 'PHPUnit\\TextUI\\Configuration\\Configuration' => '/phpunit/TextUI/Configuration/Configuration.php',
  2774. 'PHPUnit\\TextUI\\Configuration\\ConfigurationCannotBeBuiltException' => '/phpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php',
  2775. 'PHPUnit\\TextUI\\Configuration\\Constant' => '/phpunit/TextUI/Configuration/Value/Constant.php',
  2776. 'PHPUnit\\TextUI\\Configuration\\ConstantCollection' => '/phpunit/TextUI/Configuration/Value/ConstantCollection.php',
  2777. 'PHPUnit\\TextUI\\Configuration\\ConstantCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php',
  2778. 'PHPUnit\\TextUI\\Configuration\\Directory' => '/phpunit/TextUI/Configuration/Value/Directory.php',
  2779. 'PHPUnit\\TextUI\\Configuration\\DirectoryCollection' => '/phpunit/TextUI/Configuration/Value/DirectoryCollection.php',
  2780. 'PHPUnit\\TextUI\\Configuration\\DirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php',
  2781. 'PHPUnit\\TextUI\\Configuration\\Exception' => '/phpunit/TextUI/Configuration/Exception/Exception.php',
  2782. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrap' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php',
  2783. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollection' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php',
  2784. 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php',
  2785. 'PHPUnit\\TextUI\\Configuration\\File' => '/phpunit/TextUI/Configuration/Value/File.php',
  2786. 'PHPUnit\\TextUI\\Configuration\\FileCollection' => '/phpunit/TextUI/Configuration/Value/FileCollection.php',
  2787. 'PHPUnit\\TextUI\\Configuration\\FileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FileCollectionIterator.php',
  2788. 'PHPUnit\\TextUI\\Configuration\\FilterDirectory' => '/phpunit/TextUI/Configuration/Value/FilterDirectory.php',
  2789. 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php',
  2790. 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.php',
  2791. 'PHPUnit\\TextUI\\Configuration\\FilterNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php',
  2792. 'PHPUnit\\TextUI\\Configuration\\Group' => '/phpunit/TextUI/Configuration/Value/Group.php',
  2793. 'PHPUnit\\TextUI\\Configuration\\GroupCollection' => '/phpunit/TextUI/Configuration/Value/GroupCollection.php',
  2794. 'PHPUnit\\TextUI\\Configuration\\GroupCollectionIterator' => '/phpunit/TextUI/Configuration/Value/GroupCollectionIterator.php',
  2795. 'PHPUnit\\TextUI\\Configuration\\IniSetting' => '/phpunit/TextUI/Configuration/Value/IniSetting.php',
  2796. 'PHPUnit\\TextUI\\Configuration\\IniSettingCollection' => '/phpunit/TextUI/Configuration/Value/IniSettingCollection.php',
  2797. 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php',
  2798. 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php',
  2799. 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php',
  2800. 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php',
  2801. 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php',
  2802. 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php',
  2803. 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php',
  2804. 'PHPUnit\\TextUI\\Configuration\\NoConfigurationFileException' => '/phpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php',
  2805. 'PHPUnit\\TextUI\\Configuration\\NoCoverageCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php',
  2806. 'PHPUnit\\TextUI\\Configuration\\NoCustomCssFileException' => '/phpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php',
  2807. 'PHPUnit\\TextUI\\Configuration\\NoDefaultTestSuiteException' => '/phpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.php',
  2808. 'PHPUnit\\TextUI\\Configuration\\NoPharExtensionDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php',
  2809. 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php',
  2810. 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php',
  2811. 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php',
  2812. 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php',
  2813. 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php',
  2814. 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php',
  2815. 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php',
  2816. 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php',
  2817. 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php',
  2818. 'PHPUnit\\TextUI\\Configuration\\TestFile' => '/phpunit/TextUI/Configuration/Value/TestFile.php',
  2819. 'PHPUnit\\TextUI\\Configuration\\TestFileCollection' => '/phpunit/TextUI/Configuration/Value/TestFileCollection.php',
  2820. 'PHPUnit\\TextUI\\Configuration\\TestFileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php',
  2821. 'PHPUnit\\TextUI\\Configuration\\TestSuite' => '/phpunit/TextUI/Configuration/Value/TestSuite.php',
  2822. 'PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder' => '/phpunit/TextUI/Configuration/TestSuiteBuilder.php',
  2823. 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollection' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollection.php',
  2824. 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.php',
  2825. 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php',
  2826. 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php',
  2827. 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php',
  2828. 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php',
  2829. 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php',
  2830. 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php',
  2831. 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php',
  2832. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
  2833. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php',
  2834. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\Subscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php',
  2835. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestConsideredRiskySubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.php',
  2836. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.php',
  2837. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFailedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php',
  2838. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php',
  2839. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php',
  2840. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php',
  2841. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php',
  2842. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
  2843. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php',
  2844. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php',
  2845. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php',
  2846. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
  2847. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
  2848. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php',
  2849. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
  2850. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
  2851. 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php',
  2852. 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php',
  2853. 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php',
  2854. 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php',
  2855. 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php',
  2856. 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php',
  2857. 'PHPUnit\\TextUI\\Output\\SummaryPrinter' => '/phpunit/TextUI/Output/SummaryPrinter.php',
  2858. 'PHPUnit\\TextUI\\Output\\TestDox\\ResultPrinter' => '/phpunit/TextUI/Output/TestDox/ResultPrinter.php',
  2859. 'PHPUnit\\TextUI\\RuntimeException' => '/phpunit/TextUI/Exception/RuntimeException.php',
  2860. 'PHPUnit\\TextUI\\ShellExitCodeCalculator' => '/phpunit/TextUI/ShellExitCodeCalculator.php',
  2861. 'PHPUnit\\TextUI\\TestDirectoryNotFoundException' => '/phpunit/TextUI/Exception/TestDirectoryNotFoundException.php',
  2862. 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php',
  2863. 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php',
  2864. 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php',
  2865. 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php',
  2866. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php',
  2867. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php',
  2868. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php',
  2869. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Crap4j' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.php',
  2870. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Html' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php',
  2871. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Php' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php',
  2872. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Text' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php',
  2873. 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Xml' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php',
  2874. 'PHPUnit\\TextUI\\XmlConfiguration\\Configuration' => '/phpunit/TextUI/Configuration/Xml/Configuration.php',
  2875. 'PHPUnit\\TextUI\\XmlConfiguration\\ConvertLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php',
  2876. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCloverToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.php',
  2877. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCrap4jToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php',
  2878. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageHtmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php',
  2879. 'PHPUnit\\TextUI\\XmlConfiguration\\CoveragePhpToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php',
  2880. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageTextToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php',
  2881. 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php',
  2882. 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php',
  2883. 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php',
  2884. 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php',
  2885. 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php',
  2886. 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php',
  2887. 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php',
  2888. 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCoverageElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.php',
  2889. 'PHPUnit\\TextUI\\XmlConfiguration\\LoadedFromFileConfiguration' => '/phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php',
  2890. 'PHPUnit\\TextUI\\XmlConfiguration\\Loader' => '/phpunit/TextUI/Configuration/Xml/Loader.php',
  2891. 'PHPUnit\\TextUI\\XmlConfiguration\\LogToReportMigration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.php',
  2892. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Junit' => '/phpunit/TextUI/Configuration/Xml/Logging/Junit.php',
  2893. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Logging' => '/phpunit/TextUI/Configuration/Xml/Logging/Logging.php',
  2894. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TeamCity' => '/phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php',
  2895. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Html' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php',
  2896. 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Text' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php',
  2897. 'PHPUnit\\TextUI\\XmlConfiguration\\Migration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php',
  2898. 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationBuilder' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php',
  2899. 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationException' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationException.php',
  2900. 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php',
  2901. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php',
  2902. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php',
  2903. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php',
  2904. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php',
  2905. 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php',
  2906. 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php',
  2907. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php',
  2908. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php',
  2909. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheResultFileAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php',
  2910. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheTokensAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php',
  2911. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveConversionToExceptionsAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php',
  2912. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.php',
  2913. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementProcessUncoveredFilesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php',
  2914. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveEmptyFilter' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php',
  2915. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveListeners' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php',
  2916. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.php',
  2917. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLoggingElements' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php',
  2918. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveNoInteractionAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php',
  2919. 'PHPUnit\\TextUI\\XmlConfiguration\\RemovePrinterAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php',
  2920. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestDoxGroupsElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php',
  2921. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestSuiteLoaderAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php',
  2922. 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveVerboseAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php',
  2923. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php',
  2924. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php',
  2925. 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php',
  2926. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php',
  2927. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php',
  2928. 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php',
  2929. 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php',
  2930. 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php',
  2931. 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php',
  2932. 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php',
  2933. 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php',
  2934. 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php',
  2935. 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php',
  2936. 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php',
  2937. 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php',
  2938. 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php',
  2939. 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php',
  2940. 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php',
  2941. 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php',
  2942. 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php',
  2943. 'PHPUnit\\Util\\Http\\Downloader' => '/phpunit/Util/Http/Downloader.php',
  2944. 'PHPUnit\\Util\\Http\\PhpDownloader' => '/phpunit/Util/Http/PhpDownloader.php',
  2945. 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php',
  2946. 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php',
  2947. 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php',
  2948. 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php',
  2949. 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php',
  2950. 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php',
  2951. 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php',
  2952. 'PHPUnit\\Util\\Reflection' => '/phpunit/Util/Reflection.php',
  2953. 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php',
  2954. 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php',
  2955. 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php',
  2956. 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php',
  2957. 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php',
  2958. 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php'] as $file) {
  2959. require_once 'phar://phpunit-10.5.40.phar' . $file;
  2960. }
  2961. require __PHPUNIT_PHAR_ROOT__ . '/phpunit/Framework/Assert/Functions.php';
  2962. if ($execute) {
  2963. if (isset($printComposerLock)) {
  2964. print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/composer.lock');
  2965. exit;
  2966. }
  2967. if (isset($printManifest)) {
  2968. print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt');
  2969. exit;
  2970. }
  2971. if (isset($printSbom)) {
  2972. print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/sbom.xml');
  2973. exit;
  2974. }
  2975. unset($execute);
  2976. exit((new PHPUnit\TextUI\Application)->run($_SERVER['argv']));
  2977. }
  2978. __HALT_COMPILER(); ?>
  2979. èä����������phpunit-10.5.40.phar���� ���composer.lockÉÚ��ÒVfgÉÚ��~dùT¤������ ���manifest.txtç��ÒVfgç��ãP²F¤������'���myclabs-deep-copy/DeepCopy/DeepCopy.php2 ��ÒVfg2 ��¿Íˆ‹¤������7���myclabs-deep-copy/DeepCopy/Exception/CloneException.phpŠ���ÒVfgŠ���JDéȤ������:���myclabs-deep-copy/DeepCopy/Exception/PropertyException.phpƒ���ÒVfgƒ���o‘¼#¤������5���myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.phpË��ÒVfgË��–=(e¤������G���myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php��ÒVfg��JZEé¤������L���myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.phpð��ÒVfgð��Ÿï¡t¤������B���myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.phpª��ÒVfgª��fQc_¤������,���myclabs-deep-copy/DeepCopy/Filter/Filter.phph��ÒVfgh��¸ß½¤������0���myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php��ÒVfg��ÿ7#¤������3���myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php¤��ÒVfg¤���ÉT:¤������3���myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.phpù��ÒVfgù��Côkì¤������D���myclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php‹��ÒVfg‹�� ‹3ä¤������.���myclabs-deep-copy/DeepCopy/Matcher/Matcher.phpá���ÒVfgá���ÈfËä������6���myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.phpº��ÒVfgº��ÝÀA^¤������:���myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php��ÒVfg��Ñì¡P¤������:���myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php9��ÒVfg9��Ge잤������:���myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php9��ÒVfg9��1•¦†¤������A���myclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php“��ÒVfg“��[‚ã¤������?���myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php`��ÒVfg`��m9£œ¤������7���myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php��ÒVfg��»8;¤������;���myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.phpë���ÒVfgë���F_e ¤������?���myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.phpð��ÒVfgð��£Ø©¤������A���myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php¼���ÒVfg¼���K픤������G���myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php*��ÒVfg*��L-Ø ¤������4���myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.phpÎ���ÒVfgÎ���ÔŠ‡¤������6���myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.phpÞ��ÒVfgÞ��û×$¤������(���myclabs-deep-copy/DeepCopy/deep_copy.php¥��ÒVfg¥��¢WÈ•¤���������myclabs-deep-copy/LICENSE5��ÒVfg5��Ê­Ë„¤���������nikic-php-parser/LICENSEð��ÒVfgð��¥ä”*¤������&���nikic-php-parser/PhpParser/Builder.php×���ÒVfg×���’[ṳ������1���nikic-php-parser/PhpParser/Builder/ClassConst.php;��ÒVfg;��(kïü¤������-���nikic-php-parser/PhpParser/Builder/Class_.phpk��ÒVfgk��Ó�ÞQ¤������2���nikic-php-parser/PhpParser/Builder/Declaration.phpþ��ÒVfgþ��`X:¤������/���nikic-php-parser/PhpParser/Builder/EnumCase.phpÖ��ÒVfgÖ��ȸÚ¤������,���nikic-php-parser/PhpParser/Builder/Enum_.phpà ��ÒVfgà ��ÅUfƒ¤������3���nikic-php-parser/PhpParser/Builder/FunctionLike.php9��ÒVfg9���B¹ã¤������0���nikic-php-parser/PhpParser/Builder/Function_.php‹��ÒVfg‹��¥33A¤������1���nikic-php-parser/PhpParser/Builder/Interface_.phph
  2980. ��ÒVfgh
  2981. ��£‹·|¤������-���nikic-php-parser/PhpParser/Builder/Method.php§��ÒVfg§��Ú·t„¤������1���nikic-php-parser/PhpParser/Builder/Namespace_.phpu��ÒVfgu�� Öî¤������,���nikic-php-parser/PhpParser/Builder/Param.php¬��ÒVfg¬��_먊¤������/���nikic-php-parser/PhpParser/Builder/Property.phpx��ÒVfgx��VÆnâ¤������/���nikic-php-parser/PhpParser/Builder/TraitUse.php¼��ÒVfg¼��!�rѤ������9���nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.phpú��ÒVfgú��Œ0�¤������-���nikic-php-parser/PhpParser/Builder/Trait_.php4 ��ÒVfg4 ��ëѬZ¤������+���nikic-php-parser/PhpParser/Builder/Use_.php,��ÒVfg,��K,g¤������-���nikic-php-parser/PhpParser/BuilderFactory.php)��ÒVfg)�� –Ò½¤������-���nikic-php-parser/PhpParser/BuilderHelpers.phpl%��ÒVfgl%��‚^Š[¤������&���nikic-php-parser/PhpParser/Comment.php��ÒVfg��VUG¤������*���nikic-php-parser/PhpParser/Comment/Doc.php€���ÒVfg€����Í袤������;���nikic-php-parser/PhpParser/ConstExprEvaluationException.php}���ÒVfg}���ÍÞO¤������1���nikic-php-parser/PhpParser/ConstExprEvaluator.php&��ÒVfg&��º´¶¤������$���nikic-php-parser/PhpParser/Error.php]��ÒVfg]��×:¸¤������+���nikic-php-parser/PhpParser/ErrorHandler.php9��ÒVfg9��–yo¤������6���nikic-php-parser/PhpParser/ErrorHandler/Collecting.php•��ÒVfg•��HÏr(¤������4���nikic-php-parser/PhpParser/ErrorHandler/Throwing.php˜��ÒVfg˜��Îr¾£¤������0���nikic-php-parser/PhpParser/Internal/DiffElem.php
  2982. ��ÒVfg
  2983. ��à_P¤������.���nikic-php-parser/PhpParser/Internal/Differ.phpÇ��ÒVfgÇ��d;v,¤������A���nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.phpe
  2984. ��ÒVfge
  2985. ��²G×o¤������5���nikic-php-parser/PhpParser/Internal/TokenPolyfill.php·$��ÒVfg·$��wdz®¤������3���nikic-php-parser/PhpParser/Internal/TokenStream.php£#��ÒVfg£#��GzÙ¤������*���nikic-php-parser/PhpParser/JsonDecoder.php® ��ÒVfg® ��
  2986. øn¤������$���nikic-php-parser/PhpParser/Lexer.php(��ÒVfg(��&Àì�¤������.���nikic-php-parser/PhpParser/Lexer/Emulative.phpC ��ÒVfgC ��œšÞ¤������T���nikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php² ��ÒVfg² ��ÑÆÍ�¤������D���nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.phpÏ��ÒVfgÏ��æ g$¤������D���nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php¾��ÒVfg¾���¿¾¤������H���nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php��ÒVfg��HU¨j¤������B���nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php2��ÒVfg2��$ÐG­¤������E���nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.phpÈ��ÒVfgÈ��Â9æG¤������H���nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php-��ÒVfg-��[SŤ������H���nikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php×��ÒVfg×��ü4"Ù¤������P���nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.phpõ��ÒVfgõ��ÜP“Τ������H���nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.phpd��ÒVfgd��/Cê¤������B���nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php��ÒVfg��ï—‚Ù¤������@���nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.phpW��ÒVfgW��3˜�ù¤������(���nikic-php-parser/PhpParser/Modifiers.phpF
  2987. ��ÒVfgF
  2988. ��`ؤ������*���nikic-php-parser/PhpParser/NameContext.php &��ÒVfg &�� 8ÄÕ¤������#���nikic-php-parser/PhpParser/Node.php��ÒVfg��¶h¦m¤������'���nikic-php-parser/PhpParser/Node/Arg.php ��ÒVfg ��#Eªˆ¤������-���nikic-php-parser/PhpParser/Node/ArrayItem.phpÞ��ÒVfgÞ��¸ªÙݤ������-���nikic-php-parser/PhpParser/Node/Attribute.php`��ÒVfg`��–v¤������2���nikic-php-parser/PhpParser/Node/AttributeGroup.php¨��ÒVfg¨��Gãiʤ������.���nikic-php-parser/PhpParser/Node/ClosureUse.phpî��ÒVfgî��\±jt¤������/���nikic-php-parser/PhpParser/Node/ComplexType.php[��ÒVfg[��š0Us¤������*���nikic-php-parser/PhpParser/Node/Const_.phpë��ÒVfgë��T¼=y¤������/���nikic-php-parser/PhpParser/Node/DeclareItem.php ��ÒVfg ��¸o#¤������(���nikic-php-parser/PhpParser/Node/Expr.php����ÒVfg����|Å)¬¤������6���nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.phpW��ÒVfgW��Sé!¤������2���nikic-php-parser/PhpParser/Node/Expr/ArrayItem.php`���ÒVfg`���t<&]¤������/���nikic-php-parser/PhpParser/Node/Expr/Array_.phpr��ÒVfgr��§sG¤������6���nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php>
  2989. ��ÒVfg>
  2990. ��«�ÚM¤������/���nikic-php-parser/PhpParser/Node/Expr/Assign.php'��ÒVfg'��0)œ
  2991. ¤������1���nikic-php-parser/PhpParser/Node/Expr/AssignOp.phpô��ÒVfgô��¢Œb/¤������<���nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php��ÒVfg��Æ?Q¤������;���nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php��ÒVfg��)Þñ¤������<���nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php��ÒVfg��&ÉTþ¤������:���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php��ÒVfg��9˜·¤¤������8���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.phpÿ���ÒVfgÿ���GÅ3¤������5���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.phpù���ÒVfgù���ÍÔ/¤������7���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.phpý���ÒVfgý���¦„¶c¤������5���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.phpù���ÒVfgù���Ãj�Œ¤������5���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.phpù���ÒVfgù���Y:Å;¤������6���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.phpû���ÒVfgû���KÍã]¤������5���nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.phpù���ÒVfgù���ߊÍA¤������;���nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php��ÒVfg��–(?¤������<���nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php��ÒVfg��®·íâ¤������2���nikic-php-parser/PhpParser/Node/Expr/AssignRef.phpX��ÒVfgX��[—·¤������1���nikic-php-parser/PhpParser/Node/Expr/BinaryOp.phpd��ÒVfgd��ñ`˜­¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.phpV��ÒVfgV��NVD¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.phpT��ÒVfgT��ÝŸ�¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.phpV��ÒVfgV��à3$¶¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpW��ÒVfgW��ú€Ýÿ¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.phpU��ÒVfgU��‰¡G¤������:���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.phpS��ÒVfgS��¯�/à¤������8���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.phpN��ÒVfgN��¶€¤������5���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.phpH��ÒVfgH��¨A+¤������7���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.phpM��ÒVfgM��á$3¤������9���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.phpP��ÒVfgP��X‡Š¤������@���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php_��ÒVfg_��³Âå ¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.phpV��ÒVfgV��´Ðã¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpX��ÒVfgX��Fü—=¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.phpU��ÒVfgU��-”š3¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpX��ÒVfgX��ÞÁŠé¤������7���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.phpL��ÒVfgL��"7®æ¤������5���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.phpH��ÒVfgH��Ó
  2992. ñ¤������5���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.phpH��ÒVfgH�� �œt¤������:���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.phpS��ÒVfgS��¨½£Í¤������>���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php\��ÒVfg\���õc_¤������6���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.phpJ��ÒVfgJ��cm¤������5���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.phpI��ÒVfgI��­Þ,ô¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.phpU��ÒVfgU��C”Xe¤������<���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpW��ÒVfgW��ü;‘¤������9���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.phpP��ÒVfgP��T—�å¤������@���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php_��ÒVfg_��èJ³¤������;���nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.phpV��ÒVfgV��ã”Ex¤������3���nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php­��ÒVfg­��}lMˤ������3���nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php­��ÒVfg­��sÂ7Þ¤������1���nikic-php-parser/PhpParser/Node/Expr/CallLike.php���ÒVfg���#™š¤������-���nikic-php-parser/PhpParser/Node/Expr/Cast.phpU��ÒVfgU��¼ö³ð¤������4���nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.phpî���ÒVfgî���ȯ¾š¤������3���nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.phpì���ÒVfgì���ª¡>¤������4���nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php·��ÒVfg·��S(Û¤������2���nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.phpê���ÒVfgê���ó,Íœ¤������5���nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.phpð���ÒVfgð���\­‘°¤������5���nikic-php-parser/PhpParser/Node/Expr/Cast/String_.phpð���ÒVfgð���*uÚ¤������4���nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.phpî���ÒVfgî���É”™Ô¤������8���nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php��ÒVfg���2å¤������/���nikic-php-parser/PhpParser/Node/Expr/Clone_.phpž��ÒVfgž��™×¤������0���nikic-php-parser/PhpParser/Node/Expr/Closure.phpj ��ÒVfgj ��òI¶¤������3���nikic-php-parser/PhpParser/Node/Expr/ClosureUse.phpa���ÒVfga���‚‰ðé¤������3���nikic-php-parser/PhpParser/Node/Expr/ConstFetch.phpØ��ÒVfgØ��s�>6¤������/���nikic-php-parser/PhpParser/Node/Expr/Empty_.php¡��ÒVfg¡��¸¨Ý¤������.���nikic-php-parser/PhpParser/Node/Expr/Error.php��ÒVfg��$ŸLŒ¤������6���nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php·��ÒVfg·��Î &¤������.���nikic-php-parser/PhpParser/Node/Expr/Eval_.phpž��ÒVfgž��A[¤������.���nikic-php-parser/PhpParser/Node/Expr/Exit_.php��ÒVfg��gÝí¼¤������1���nikic-php-parser/PhpParser/Node/Expr/FuncCall.php��ÒVfg��@"]¤������1���nikic-php-parser/PhpParser/Node/Expr/Include_.phpÍ��ÒVfgÍ��—ÀÊ ¤������4���nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php•��ÒVfg•��.§B ¤������/���nikic-php-parser/PhpParser/Node/Expr/Isset_.php£��ÒVfg£��ò>:¤������.���nikic-php-parser/PhpParser/Node/Expr/List_.php£��ÒVfg£��2ò¿)¤������/���nikic-php-parser/PhpParser/Node/Expr/Match_.php;��ÒVfg;��hü¤������3���nikic-php-parser/PhpParser/Node/Expr/MethodCall.phpQ��ÒVfgQ��OD¥å¤������-���nikic-php-parser/PhpParser/Node/Expr/New_.php•��ÒVfg•��<~h¤������;���nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.phph��ÒVfgh��k[˜S¤������>���nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php��ÒVfg��k*¢¤������0���nikic-php-parser/PhpParser/Node/Expr/PostDec.php ��ÒVfg ��Ph@¤������0���nikic-php-parser/PhpParser/Node/Expr/PostInc.php ��ÒVfg ��dÞ‡¤������/���nikic-php-parser/PhpParser/Node/Expr/PreDec.php���ÒVfg���ÍmB'¤������/���nikic-php-parser/PhpParser/Node/Expr/PreInc.php���ÒVfg���Ô·$x¤������/���nikic-php-parser/PhpParser/Node/Expr/Print_.php¡��ÒVfg¡��U¤óô¤������6���nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.phpê��ÒVfgê��:%g¤������2���nikic-php-parser/PhpParser/Node/Expr/ShellExec.phpH��ÒVfgH��edü¤������3���nikic-php-parser/PhpParser/Node/Expr/StaticCall.php\��ÒVfg\��©ÁP¼¤������<���nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php;��ÒVfg;��ç.½ ¤������0���nikic-php-parser/PhpParser/Node/Expr/Ternary.phpè��ÒVfgè��:X(¤������/���nikic-php-parser/PhpParser/Node/Expr/Throw_.php½��ÒVfg½��#‚6¢¤������3���nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php­��ÒVfg­��¾*C‰¤������2���nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.phpª��ÒVfgª��F!Ä�¤������1���nikic-php-parser/PhpParser/Node/Expr/Variable.phpž��ÒVfgž��ìEk¤������2���nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php»��ÒVfg»��ôBß ¤������/���nikic-php-parser/PhpParser/Node/Expr/Yield_.phpo��ÒVfgo���‘Æ´¤������0���nikic-php-parser/PhpParser/Node/FunctionLike.phpï��ÒVfgï��Êj¸¤������.���nikic-php-parser/PhpParser/Node/Identifier.phpA��ÒVfgA��5€¤������:���nikic-php-parser/PhpParser/Node/InterpolatedStringPart.phpr��ÒVfgr��kGþn¤������4���nikic-php-parser/PhpParser/Node/IntersectionType.php¯��ÒVfg¯��€”u«¤������,���nikic-php-parser/PhpParser/Node/MatchArm.phpÓ��ÒVfgÓ��'Ãb?¤������(���nikic-php-parser/PhpParser/Node/Name.phpÈ!��ÒVfgÈ!��Ü ó�¤������7���nikic-php-parser/PhpParser/Node/Name/FullyQualified.phpÂ��ÒVfgÂ��ø 2�¤������1���nikic-php-parser/PhpParser/Node/Name/Relative.php¿��ÒVfg¿��‰8½V¤������0���nikic-php-parser/PhpParser/Node/NullableType.phpÈ��ÒVfgÈ��Õä¤������)���nikic-php-parser/PhpParser/Node/Param.php¢ ��ÒVfg¢ ��#)¿¬¤������0���nikic-php-parser/PhpParser/Node/PropertyHook.php{ ��ÒVfg{ ��óÿ™Ú¤������0���nikic-php-parser/PhpParser/Node/PropertyItem.php\��ÒVfg\��¦`º¤������*���nikic-php-parser/PhpParser/Node/Scalar.phpo���ÒVfgo���­¦þ=¤������2���nikic-php-parser/PhpParser/Node/Scalar/DNumber.phpZ���ÒVfgZ���W±˜¤������3���nikic-php-parser/PhpParser/Node/Scalar/Encapsed.phpf���ÒVfgf����†‹¤������=���nikic-php-parser/PhpParser/Node/Scalar/EncapsedStringPart.phpm���ÒVfgm���8I懤������1���nikic-php-parser/PhpParser/Node/Scalar/Float_.phpW��ÒVfgW��j©Æ¤������/���nikic-php-parser/PhpParser/Node/Scalar/Int_.phpø ��ÒVfgø ��Ÿ‘¤������=���nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.phpÝ��ÒVfgÝ��?à Z¤������2���nikic-php-parser/PhpParser/Node/Scalar/LNumber.phpX���ÒVfgX���äæÃð¤������5���nikic-php-parser/PhpParser/Node/Scalar/MagicConst.phpx��ÒVfgx��÷Ï®÷¤������<���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.phpZ��ÒVfgZ��ÁÆÓ5¤������9���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.phpS��ÒVfgS��rÙfɤ������:���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.phpV��ÒVfgV��6›Q¤������?���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.phpc��ÒVfgc��—5¤¤������:���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.phpV��ÒVfgV��èDEš¤������<���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php\��ÒVfg\��Ë2 N¤������@���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.phpf��ÒVfgf��‹Ãq¤������>���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.phpb��ÒVfgb��0º�«¤������<���nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.phpZ��ÒVfgZ��˵ݤ������2���nikic-php-parser/PhpParser/Node/Scalar/String_.phpº��ÒVfgº��Øz�¤������-���nikic-php-parser/PhpParser/Node/StaticVar.php��ÒVfg��ñT>�¤������(���nikic-php-parser/PhpParser/Node/Stmt.php����ÒVfg����«yþ¤������.���nikic-php-parser/PhpParser/Node/Stmt/Block.php§��ÒVfg§��×j¤������/���nikic-php-parser/PhpParser/Node/Stmt/Break_.phpÛ��ÒVfgÛ��mj–¤������.���nikic-php-parser/PhpParser/Node/Stmt/Case_.php†��ÒVfg†��ݸO/¤������/���nikic-php-parser/PhpParser/Node/Stmt/Catch_.phpy��ÒVfgy��{é^}¤������3���nikic-php-parser/PhpParser/Node/Stmt/ClassConst.phpS��ÒVfgS��/꾬¤������2���nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php ��ÒVfg ��3Îq¦¤������4���nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php÷��ÒVfg÷�� #c¤������/���nikic-php-parser/PhpParser/Node/Stmt/Class_.php¸ ��ÒVfg¸ ��Æ1è?¤������/���nikic-php-parser/PhpParser/Node/Stmt/Const_.phpÙ��ÒVfgÙ��>9øù¤������2���nikic-php-parser/PhpParser/Node/Stmt/Continue_.phpê��ÒVfgê��Çò¥€¤������7���nikic-php-parser/PhpParser/Node/Stmt/DeclareDeclare.phpb���ÒVfgb���[Š Ñ¤������1���nikic-php-parser/PhpParser/Node/Stmt/Declare_.php½��ÒVfg½��5‹`ä¤������,���nikic-php-parser/PhpParser/Node/Stmt/Do_.phpT��ÒVfgT��%ú0�¤������.���nikic-php-parser/PhpParser/Node/Stmt/Echo_.php´��ÒVfg´��±°`)¤������0���nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php[��ÒVfg[��bE·Ñ¤������.���nikic-php-parser/PhpParser/Node/Stmt/Else_.php·��ÒVfg·��&ô¡Á¤������1���nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php»��ÒVfg»��w4m¤������.���nikic-php-parser/PhpParser/Node/Stmt/Enum_.phpJ��ÒVfgJ��›Œï?¤������3���nikic-php-parser/PhpParser/Node/Stmt/Expression.php÷��ÒVfg÷�� À¤������1���nikic-php-parser/PhpParser/Node/Stmt/Finally_.php¿��ÒVfg¿��8ååå¤������-���nikic-php-parser/PhpParser/Node/Stmt/For_.php¼��ÒVfg¼��€‚½+¤������1���nikic-php-parser/PhpParser/Node/Stmt/Foreach_.phpÐ��ÒVfgÐ��µ0–פ������2���nikic-php-parser/PhpParser/Node/Stmt/Function_.php¬
  2993. ��ÒVfg¬
  2994. ��f*키������0���nikic-php-parser/PhpParser/Node/Stmt/Global_.phpÇ��ÒVfgÇ��Po6¤������.���nikic-php-parser/PhpParser/Node/Stmt/Goto_.php"��ÒVfg"��ÐX –¤������1���nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php^��ÒVfg^��€¦7Ѥ������5���nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php!��ÒVfg!��˜×y¤������,���nikic-php-parser/PhpParser/Node/Stmt/If_.php‘��ÒVfg‘��4‡o¤������3���nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php´��ÒVfg´��oûȇ¤������3���nikic-php-parser/PhpParser/Node/Stmt/Interface_.phpN��ÒVfgN��™yáÆ¤������.���nikic-php-parser/PhpParser/Node/Stmt/Label.phpü��ÒVfgü��ŸäJ¤������3���nikic-php-parser/PhpParser/Node/Stmt/Namespace_.phpÝ��ÒVfgÝ��SvEj¤������,���nikic-php-parser/PhpParser/Node/Stmt/Nop.phpF��ÒVfgF��$6¿Ø¤������1���nikic-php-parser/PhpParser/Node/Stmt/Property.phpŠ ��ÒVfgŠ ��θ y¤������9���nikic-php-parser/PhpParser/Node/Stmt/PropertyProperty.phpc���ÒVfgc���÷Èݦ¤������0���nikic-php-parser/PhpParser/Node/Stmt/Return_.phpÈ��ÒVfgÈ��|M¤������2���nikic-php-parser/PhpParser/Node/Stmt/StaticVar.php`���ÒVfg`���ÌdTv¤������0���nikic-php-parser/PhpParser/Node/Stmt/Static_.phpþ��ÒVfgþ��’ٜޤ������0���nikic-php-parser/PhpParser/Node/Stmt/Switch_.phpI��ÒVfgI��iËÇü¤������1���nikic-php-parser/PhpParser/Node/Stmt/TraitUse.phpš��ÒVfgš��?óô\¤������;���nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php=��ÒVfg=��{:Ф������A���nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php1��ÒVfg1��b Ö¤������F���nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php>��ÒVfg>��¶Ñÿ ¤������/���nikic-php-parser/PhpParser/Node/Stmt/Trait_.phpQ��ÒVfgQ��ËEøQ¤������1���nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php6��ÒVfg6��‚ã2.¤������/���nikic-php-parser/PhpParser/Node/Stmt/Unset_.php¿��ÒVfg¿��:VÉɤ������/���nikic-php-parser/PhpParser/Node/Stmt/UseUse.php^���ÒVfg^���Ë‹íQ¤������-���nikic-php-parser/PhpParser/Node/Stmt/Use_.phpÔ��ÒVfgÔ�� Ç|¤������/���nikic-php-parser/PhpParser/Node/Stmt/While_.phpW��ÒVfgW��Q/£×¤������-���nikic-php-parser/PhpParser/Node/UnionType.php»��ÒVfg»��’Hš­¤������+���nikic-php-parser/PhpParser/Node/UseItem.phpÇ��ÒVfgÇ��73Uƒ¤������5���nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php��ÒVfg��y�.¤������7���nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php¯��ÒVfg¯��mäWè¤������+���nikic-php-parser/PhpParser/NodeAbstract.php7��ÒVfg7��ë¾i‚¤������)���nikic-php-parser/PhpParser/NodeDumper.php(��ÒVfg(��¸°Q¤������)���nikic-php-parser/PhpParser/NodeFinder.phpW
  2995. ��ÒVfgW
  2996. ��¥¹^‘¤������,���nikic-php-parser/PhpParser/NodeTraverser.phpí'��ÒVfgí'��'÷G[¤������5���nikic-php-parser/PhpParser/NodeTraverserInterface.phpa��ÒVfga��½©ìð¤������*���nikic-php-parser/PhpParser/NodeVisitor.phpX��ÒVfgX��Ýp}ª¤������9���nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php��ÒVfg��î"Û¤������C���nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php¶
  2997. ��ÒVfg¶
  2998. ��ªÉ^µ¤������9���nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php���ÒVfg���Q¤ÜÛ¤������>���nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php��ÒVfg��~Ĭ*¤������7���nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php(��ÒVfg(���‡�¥¤������@���nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.phpœ��ÒVfgœ��g-‘o¤������B���nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php‡��ÒVfg‡�� A¯ƒ¤������2���nikic-php-parser/PhpParser/NodeVisitorAbstract.phpÙ��ÒVfgÙ��¡¿é~¤������%���nikic-php-parser/PhpParser/Parser.php ��ÒVfg ��œ0@¤������*���nikic-php-parser/PhpParser/Parser/Php7.phpUt�ÒVfgUt� ˜Æ¤������*���nikic-php-parser/PhpParser/Parser/Php8.php�t�ÒVfg�t�x¶o!¤������-���nikic-php-parser/PhpParser/ParserAbstract.phpK½��ÒVfgK½��>‹rý¤������,���nikic-php-parser/PhpParser/ParserFactory.phpÖ��ÒVfgÖ��(ŸÉc¤������)���nikic-php-parser/PhpParser/PhpVersion.php…��ÒVfg…��.ƒq¸¤������,���nikic-php-parser/PhpParser/PrettyPrinter.php¸��ÒVfg¸��>¹—´¤������5���nikic-php-parser/PhpParser/PrettyPrinter/Standard.php%Ê��ÒVfg%Ê��È¢=­¤������4���nikic-php-parser/PhpParser/PrettyPrinterAbstract.php�ÒVfg�¨)ÕÓ¤������$���nikic-php-parser/PhpParser/Token.phpû��ÒVfgû��Çã ̤������3���nikic-php-parser/PhpParser/compatibility_tokens.phpé��ÒVfgé��W¾ÿ¤���������object-enumerator/LICENSEû��ÒVfgû��f‰œ¤���������object-reflector/LICENSEû��ÒVfgû��Rù6¤���������phar-io-manifest/LICENSE`��ÒVfg`��÷þp¤������+���phar-io-manifest/ManifestDocumentMapper.phpë��ÒVfgë��^DŒï¤������#���phar-io-manifest/ManifestLoader.phpÿ��ÒVfgÿ��ÙX©j¤������'���phar-io-manifest/ManifestSerializer.phpÏ��ÒVfgÏ��?jª'¤������:���phar-io-manifest/exceptions/ElementCollectionException.php��ÒVfg��In‡¤������)���phar-io-manifest/exceptions/Exception.phpÓ��ÒVfgÓ��Ö½Ð�¤������?���phar-io-manifest/exceptions/InvalidApplicationNameException.php<��ÒVfg<��°°¯W¤������5���phar-io-manifest/exceptions/InvalidEmailException.php��ÒVfg��)Ϫ}¤������3���phar-io-manifest/exceptions/InvalidUrlException.php ��ÒVfg ��x᳤������9���phar-io-manifest/exceptions/ManifestDocumentException.php��ÒVfg��/úï"¤������@���phar-io-manifest/exceptions/ManifestDocumentLoadingException.php~��ÒVfg~��H}»¤������?���phar-io-manifest/exceptions/ManifestDocumentMapperException.php��ÒVfg��J¯R1¤������8���phar-io-manifest/exceptions/ManifestElementException.php��ÒVfg���Ì�æ¤������7���phar-io-manifest/exceptions/ManifestLoaderException.phpä��ÒVfgä��Íl
  2999. ½¤������7���phar-io-manifest/exceptions/NoEmailAddressException.php��ÒVfg��áÁü¤������'���phar-io-manifest/values/Application.php ��ÒVfg ��;Äk¤������+���phar-io-manifest/values/ApplicationName.php…��ÒVfg…��á”ù¤������"���phar-io-manifest/values/Author.php���ÒVfg���÷x•ü¤������,���phar-io-manifest/values/AuthorCollection.php-��ÒVfg-��àÍá¤������4���phar-io-manifest/values/AuthorCollectionIterator.php¡��ÒVfg¡��¨Ðªe¤������,���phar-io-manifest/values/BundledComponent.phpd��ÒVfgd��7õõ¤������6���phar-io-manifest/values/BundledComponentCollection.php¹��ÒVfg¹��·æߤ������>���phar-io-manifest/values/BundledComponentCollectionIterator.php��ÒVfg�� _»¤������0���phar-io-manifest/values/CopyrightInformation.phpp��ÒVfgp��‚“æP¤������!���phar-io-manifest/values/Email.php¦��ÒVfg¦��«S·¤������%���phar-io-manifest/values/Extension.phpÅ��ÒVfgÅ��F {¤������#���phar-io-manifest/values/Library.php��ÒVfg��±ýžv¤������#���phar-io-manifest/values/License.php��ÒVfg��4Êýç¤������$���phar-io-manifest/values/Manifest.php&
  3000. ��ÒVfg&
  3001. ��¾øüú¤������3���phar-io-manifest/values/PhpExtensionRequirement.php¼��ÒVfg¼��²Pη¤������1���phar-io-manifest/values/PhpVersionRequirement.phpA��ÒVfgA��Äñi‰¤������'���phar-io-manifest/values/Requirement.php´��ÒVfg´�� ŸïU¤������1���phar-io-manifest/values/RequirementCollection.phps��ÒVfgs��6ý•M¤������9���phar-io-manifest/values/RequirementCollectionIterator.phpÝ��ÒVfgÝ��Uޤ������ ���phar-io-manifest/values/Type.phpÔ��ÒVfgÔ��ܲ3«¤���������phar-io-manifest/values/Url.phpÁ��ÒVfgÁ��ëO©ƒ¤������&���phar-io-manifest/xml/AuthorElement.phpð��ÒVfgð��ÎÊÂÚ¤������0���phar-io-manifest/xml/AuthorElementCollection.phpM��ÒVfgM��j£·¤������'���phar-io-manifest/xml/BundlesElement.phpt��ÒVfgt��]Y´‹¤������)���phar-io-manifest/xml/ComponentElement.php™��ÒVfg™��”na¤������3���phar-io-manifest/xml/ComponentElementCollection.phpV��ÒVfgV��ú¥?¤������(���phar-io-manifest/xml/ContainsElement.phpŒ��ÒVfgŒ��l8è¤������)���phar-io-manifest/xml/CopyrightElement.phpó��ÒVfgó��¹hDp¤������*���phar-io-manifest/xml/ElementCollection.phpÂ��ÒVfgÂ��<^ÉÞ¤������#���phar-io-manifest/xml/ExtElement.php*��ÒVfg*��^º×¤������-���phar-io-manifest/xml/ExtElementCollection.phpD��ÒVfgD��βSó¤������)���phar-io-manifest/xml/ExtensionElement.php���ÒVfg���€ JŒ¤������'���phar-io-manifest/xml/LicenseElement.php���ÒVfg���vâ/!¤������)���phar-io-manifest/xml/ManifestDocument.phpƒ ��ÒVfgƒ ��™Åi_¤������(���phar-io-manifest/xml/ManifestElement.phpÝ��ÒVfgÝ��#¨=¤������#���phar-io-manifest/xml/PhpElement.php��ÒVfg��Yʤ������(���phar-io-manifest/xml/RequiresElement.phpE��ÒVfgE��dwʤ������!���phar-io-version/BuildMetaData.phpã��ÒVfgã��3A(*¤���������phar-io-version/LICENSE&��ÒVfg&��Òª ¤������$���phar-io-version/PreReleaseSuffix.php��ÒVfg��8^æ¤���������phar-io-version/Version.phpñ��ÒVfgñ��‘¬¤������+���phar-io-version/VersionConstraintParser.phpN ��ÒVfgN ��n­%ˤ������*���phar-io-version/VersionConstraintValue.phpA
  3002. ��ÒVfgA
  3003. ��²fi™¤������!���phar-io-version/VersionNumber.phpµ��ÒVfgµ��Kp‘_¤������9���phar-io-version/constraints/AbstractVersionConstraint.phpÁ��ÒVfgÁ��42ƒo¤������9���phar-io-version/constraints/AndVersionConstraintGroup.phpé��ÒVfgé��k�O•¤������4���phar-io-version/constraints/AnyVersionConstraint.phpT��ÒVfgT��¸v¤������6���phar-io-version/constraints/ExactVersionConstraint.phpÖ��ÒVfgÖ��gÉÐq¤������E���phar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php‰��ÒVfg‰��©ÞÚ_¤������8���phar-io-version/constraints/OrVersionConstraintGroup.php��ÒVfg��£¥ƒ6¤������F���phar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.phpÌ��ÒVfgÌ��Bº”,¤������>���phar-io-version/constraints/SpecificMajorVersionConstraint.php ��ÒVfg ��êÒé¤������1���phar-io-version/constraints/VersionConstraint.phpø��ÒVfgø��ï¾dã¤������(���phar-io-version/exceptions/Exception.php³��ÒVfg³��ôÓ<²¤������?���phar-io-version/exceptions/InvalidPreReleaseSuffixException.php›���ÒVfg›���Ë[–¤������6���phar-io-version/exceptions/InvalidVersionException.php¡���ÒVfg¡���·ðy¤������7���phar-io-version/exceptions/NoBuildMetaDataException.php“���ÒVfg“���+${¡¤������:���phar-io-version/exceptions/NoPreReleaseSuffixException.php–���ÒVfg–���º"Ï÷¤������D���phar-io-version/exceptions/UnsupportedVersionConstraintException.phpß��ÒVfgß��¤´æ¨¤������"���php-code-coverage/CodeCoverage.php%A��ÒVfg%A��Y޵9¤������4���php-code-coverage/Data/ProcessedCodeCoverageData.phpX'��ÒVfgX'��Èb�ܤ������.���php-code-coverage/Data/RawCodeCoverageData.phpó#��ÒVfgó#��ïºÙI¤������#���php-code-coverage/Driver/Driver.php× ��ÒVfg× ��“âYÖ¤������'���php-code-coverage/Driver/PcovDriver.phpå��ÒVfgå��å=� ¤������%���php-code-coverage/Driver/Selector.phpC��ÒVfgC��‚Œ;I¤������)���php-code-coverage/Driver/XdebugDriver.php��ÒVfg��Ÿ×d¤������J���php-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.phpÇ��ÒVfgÇ��z¤������F���php-code-coverage/Exception/DeadCodeDetectionNotSupportedException.phpÃ��ÒVfgÃ��†ožI¤������C���php-code-coverage/Exception/DirectoryCouldNotBeCreatedException.phpÿ��ÒVfgÿ��<î6'¤������)���php-code-coverage/Exception/Exception.php���ÒVfg���+’ËQ¤������>���php-code-coverage/Exception/FileCouldNotBeWrittenException.php»��ÒVfg»���£ó’¤������8���php-code-coverage/Exception/InvalidArgumentException.php¨��ÒVfg¨��lÕ~Ф������F���php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php3��ÒVfg3��5oYC¤������]���php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.phpe��ÒVfge��®X3Ÿ¤������/���php-code-coverage/Exception/ParserException.php¬��ÒVfg¬��pÏêÚ¤������D���php-code-coverage/Exception/PathExistsButIsNotDirectoryException.php¥��ÒVfg¥��i�kd¤������9���php-code-coverage/Exception/PcovNotAvailableException.phpi��ÒVfgi��Áq¤������3���php-code-coverage/Exception/ReflectionException.php°��ÒVfg°��ö`�¤������?���php-code-coverage/Exception/ReportAlreadyFinalizedException.php>��ÒVfg>��ÒmU=¤������I���php-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.phpÆ��ÒVfgÆ��Ûpé¤������6���php-code-coverage/Exception/TestIdMissingException.php��ÒVfg��3ÄOê¤������C���php-code-coverage/Exception/UnintentionallyCoveredCodeException.php·��ÒVfg·��{:�¤������=���php-code-coverage/Exception/WriteOperationFailedException.php���ÒVfg���u�䶤������;���php-code-coverage/Exception/XdebugNotAvailableException.phpm��ÒVfgm��í{F¤������9���php-code-coverage/Exception/XdebugNotEnabledException.php³��ÒVfg³��J]0¤������,���php-code-coverage/Exception/XmlException.php©��ÒVfg©��0)ƒR¤���������php-code-coverage/Filter.phpb ��ÒVfgb ��‚7ñb¤���������php-code-coverage/LICENSEû��ÒVfgû��>öR¤������'���php-code-coverage/Node/AbstractNode.php��ÒVfg��1*3¤������"���php-code-coverage/Node/Builder.php[��ÒVfg[��\:š¤������$���php-code-coverage/Node/CrapIndex.phpË��ÒVfgË��²¤������$���php-code-coverage/Node/Directory.php1$��ÒVfg1$��ua¤���������php-code-coverage/Node/File.phpDW��ÒVfgDW��vÈ ¤������#���php-code-coverage/Node/Iterator.phpu��ÒVfgu��Bì0»¤������#���php-code-coverage/Report/Clover.phpJ(��ÒVfgJ(��–<z¤������&���php-code-coverage/Report/Cobertura.phpS1��ÒVfgS1��=´€¤������#���php-code-coverage/Report/Crap4j.php;��ÒVfg;��7½Â¤������(���php-code-coverage/Report/Html/Colors.phpÄ��ÒVfgÄ��géc¤������/���php-code-coverage/Report/Html/CustomCssFile.php;��ÒVfg;��y�J¦¤������(���php-code-coverage/Report/Html/Facade.php¶��ÒVfg¶��àï©Ú¤������*���php-code-coverage/Report/Html/Renderer.phpÅ ��ÒVfgÅ ��¤ýÒ¤������4���php-code-coverage/Report/Html/Renderer/Dashboard.php¢!��ÒVfg¢!��×Þôܤ������4���php-code-coverage/Report/Html/Renderer/Directory.phpK��ÒVfgK��¹88a¤������/���php-code-coverage/Report/Html/Renderer/File.phpàŠ��ÒVfgàŠ��謣¤������B���php-code-coverage/Report/Html/Renderer/Template/branches.html.distô��ÒVfgô��h2+¤������F���php-code-coverage/Report/Html/Renderer/Template/coverage_bar.html.dist'��ÒVfg'��õO}¤������M���php-code-coverage/Report/Html/Renderer/Template/coverage_bar_branch.html.dist'��ÒVfg'��õO}¤������E���php-code-coverage/Report/Html/Renderer/Template/css/bootstrap.min.cssØy�ÒVfgØy��ŽÄ¤������>���php-code-coverage/Report/Html/Renderer/Template/css/custom.css����ÒVfg��������¤������A���php-code-coverage/Report/Html/Renderer/Template/css/nv.d3.min.cssX%��ÒVfgX%���0,¤������@���php-code-coverage/Report/Html/Renderer/Template/css/octicons.cssX���ÒVfgX���'#ï¤������=���php-code-coverage/Report/Html/Renderer/Template/css/style.cssH
  3004. ��ÒVfgH
  3005. ��ÈBѺ¤������C���php-code-coverage/Report/Html/Renderer/Template/dashboard.html.dist›��ÒVfg›��×…D¤������J���php-code-coverage/Report/Html/Renderer/Template/dashboard_branch.html.dist›��ÒVfg›��×…D¤������C���php-code-coverage/Report/Html/Renderer/Template/directory.html.distö��ÒVfgö��ÎÕ†á¤������J���php-code-coverage/Report/Html/Renderer/Template/directory_branch.html.dist”��ÒVfg”��n2]¤������H���php-code-coverage/Report/Html/Renderer/Template/directory_item.html.distA��ÒVfgA��ds¤������O���php-code-coverage/Report/Html/Renderer/Template/directory_item_branch.html.dist;��ÒVfg;��ªm½Û¤������>���php-code-coverage/Report/Html/Renderer/Template/file.html.distP ��ÒVfgP ��jƒî*¤������E���php-code-coverage/Report/Html/Renderer/Template/file_branch.html.distí ��ÒVfgí ��×㉞¤������C���php-code-coverage/Report/Html/Renderer/Template/file_item.html.distr��ÒVfgr��éð/y¤������J���php-code-coverage/Report/Html/Renderer/Template/file_item_branch.html.distl��ÒVfgl��¡-°÷¤������C���php-code-coverage/Report/Html/Renderer/Template/icons/file-code.svg0��ÒVfg0��ÙQUU¤������H���php-code-coverage/Report/Html/Renderer/Template/icons/file-directory.svgê���ÒVfgê���ýÚZÿ¤������C���php-code-coverage/Report/Html/Renderer/Template/js/bootstrap.min.jscô��ÒVfgcô��Ü"#¤������<���php-code-coverage/Report/Html/Renderer/Template/js/d3.min.js­P�ÒVfg­P�Åhéb¤������:���php-code-coverage/Report/Html/Renderer/Template/js/file.jsù��ÒVfgù��b�䆤������@���php-code-coverage/Report/Html/Renderer/Template/js/jquery.min.js@^�ÒVfg@^� ָФ������?���php-code-coverage/Report/Html/Renderer/Template/js/nv.d3.min.jsÚR�ÒVfgÚR�<Ms¤������@���php-code-coverage/Report/Html/Renderer/Template/js/popper.min.jsñR��ÒVfgñR��QŠd“¤������>���php-code-coverage/Report/Html/Renderer/Template/line.html.distÅ���ÒVfgÅ���ãç­{¤������?���php-code-coverage/Report/Html/Renderer/Template/lines.html.diste���ÒVfge���df ¤������E���php-code-coverage/Report/Html/Renderer/Template/method_item.html.dist«��ÒVfg«��‹jפ������L���php-code-coverage/Report/Html/Renderer/Template/method_item_branch.html.dist¥��ÒVfg¥��yÄŽk¤������?���php-code-coverage/Report/Html/Renderer/Template/paths.html.distò��ÒVfgò��ã*'ݤ������ ���php-code-coverage/Report/PHP.php'��ÒVfg'��;Ší¤������!���php-code-coverage/Report/Text.phpË&��ÒVfgË&��»+ßÒ¤������'���php-code-coverage/Report/Thresholds.phpW��ÒVfgW��&ìa¤������1���php-code-coverage/Report/Xml/BuildInformation.phpÿ��ÒVfgÿ��X5³�¤������)���php-code-coverage/Report/Xml/Coverage.phpï��ÒVfgï��5 ¯,¤������*���php-code-coverage/Report/Xml/Directory.phpí��ÒVfgí�� ôFn¤������'���php-code-coverage/Report/Xml/Facade.phpÝ!��ÒVfgÝ!��ÐÖX§¤������%���php-code-coverage/Report/Xml/File.php��ÒVfg��¯îc¤������'���php-code-coverage/Report/Xml/Method.phpC��ÒVfgC��GƒVŸ¤������%���php-code-coverage/Report/Xml/Node.phpù��ÒVfgù�� f!>¤������(���php-code-coverage/Report/Xml/Project.phpd��ÒVfgd��—û ¨¤������'���php-code-coverage/Report/Xml/Report.php ��ÒVfg ��¹dúö¤������'���php-code-coverage/Report/Xml/Source.php‚��ÒVfg‚��¥;‹ÿ¤������&���php-code-coverage/Report/Xml/Tests.phpƒ��ÒVfgƒ��zH)פ������'���php-code-coverage/Report/Xml/Totals.php˜��ÒVfg˜��å–ì­¤������%���php-code-coverage/Report/Xml/Unit.php���ÒVfg���` pŸ¤������0���php-code-coverage/StaticAnalysis/CacheWarmer.phpg��ÒVfgg��¹][7¤������8���php-code-coverage/StaticAnalysis/CachingFileAnalyser.php��ÒVfg��`D‹{¤������;���php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.phpÝ%��ÒVfgÝ%��$¤������B���php-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.phpe-��ÒVfge-�� ÉBà¤������1���php-code-coverage/StaticAnalysis/FileAnalyser.php��ÒVfg��?�¼4¤������?���php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php9��ÒVfg9��I 6¤������8���php-code-coverage/StaticAnalysis/ParsingFileAnalyser.phpÅ��ÒVfgÅ��±Ø¤������$���php-code-coverage/TestSize/Known.phpZ��ÒVfgZ��•¤G¤������$���php-code-coverage/TestSize/Large.phpÈ��ÒVfgÈ��mrÔ¤������%���php-code-coverage/TestSize/Medium.phpË��ÒVfgË��8‹¤������$���php-code-coverage/TestSize/Small.php¼��ÒVfg¼��/ÀH¤������'���php-code-coverage/TestSize/TestSize.php���ÒVfg���‚87Ť������&���php-code-coverage/TestSize/Unknown.phpk��ÒVfgk��?Š!Þ¤������(���php-code-coverage/TestStatus/Failure.phpj��ÒVfgj��Zý¤������&���php-code-coverage/TestStatus/Known.php��ÒVfg��ƒ°ô>¤������(���php-code-coverage/TestStatus/Success.phpj��ÒVfgj��Õ‘+¤������+���php-code-coverage/TestStatus/TestStatus.phpÎ��ÒVfgÎ��NxQ¢¤������(���php-code-coverage/TestStatus/Unknown.phpo��ÒVfgo��Êôg•¤������%���php-code-coverage/Util/Filesystem.php­��ÒVfg­��(У|¤������%���php-code-coverage/Util/Percentage.php^��ÒVfg^��ê&×B¤���������php-code-coverage/Version.php°��ÒVfg°��d}¤������%���php-file-iterator/ExcludeIterator.php.��ÒVfg.��Èõ�¤���������php-file-iterator/Facade.phpŽ��ÒVfgŽ��'h¤���������php-file-iterator/Factory.phpá
  3006. ��ÒVfgá
  3007. ��Ûuw¤���������php-file-iterator/Iterator.phpÐ ��ÒVfgÐ ��$"‚v¤���������php-file-iterator/LICENSEû��ÒVfgû��-~yÖ¤���������php-invoker/Invoker.phpõ��ÒVfgõ��ýÍú¤������$���php-invoker/exceptions/Exception.phpv��ÒVfgv��'P=¤������D���php-invoker/exceptions/ProcessControlExtensionNotLoadedException.php»��ÒVfg»��ÔþÓ¤������+���php-invoker/exceptions/TimeoutException.php¢��ÒVfg¢��—tJï¤���������php-text-template/LICENSEû��ÒVfgû��-~yÖ¤���������php-text-template/Template.phpV ��ÒVfgV ��Æ %X¤������*���php-text-template/exceptions/Exception.php}��ÒVfg}��Áã`"¤������9���php-text-template/exceptions/InvalidArgumentException.php¤��ÒVfg¤��ô¼¸Â¤������1���php-text-template/exceptions/RuntimeException.php¹��ÒVfg¹��Ö]Mp¤���������php-timer/Duration.php¹ ��ÒVfg¹ ��„ëߤ���������php-timer/LICENSEû��ÒVfgû��ÞãÁ»¤������$���php-timer/ResourceUsageFormatter.php���ÒVfg���65×Ĥ���������php-timer/Timer.php���ÒVfg���°©ƒý¤������"���php-timer/exceptions/Exception.phpr��ÒVfgr��˜›<¤������/���php-timer/exceptions/NoActiveTimerException.php ��ÒVfg ��*®õ¤������E���php-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.phpº��ÒVfgº��Ð.ñ¤������ ���phpunit.xsd¥F��ÒVfg¥F��6!Åå¤������1���phpunit/Event/Dispatcher/CollectingDispatcher.phpÿ��ÒVfgÿ��\´Ae¤������0���phpunit/Event/Dispatcher/DeferringDispatcher.php¢��ÒVfg¢��MW°‰¤������-���phpunit/Event/Dispatcher/DirectDispatcher.phpÒ ��ÒVfgÒ ��÷@ç]¤������'���phpunit/Event/Dispatcher/Dispatcher.php}��ÒVfg}��;G`œ¤������3���phpunit/Event/Dispatcher/SubscribableDispatcher.php��ÒVfg��»>òL¤������,���phpunit/Event/Emitter/DispatchingEmitter.php»r��ÒVfg»r��a a¤������!���phpunit/Event/Emitter/Emitter.phpw*��ÒVfgw*��P`¤������-���phpunit/Event/Events/Application/Finished.php‡��ÒVfg‡��‘
  3008. ¨¿¤������7���phpunit/Event/Events/Application/FinishedSubscriber.php6��ÒVfg6��Íþ)÷¤������,���phpunit/Event/Events/Application/Started.php…��ÒVfg…��Âæ›i¤������6���phpunit/Event/Events/Application/StartedSubscriber.php4��ÒVfg4��JÜ'¤���������phpunit/Event/Events/Event.php
  3009. ��ÒVfg
  3010. ��íì· ¤������(���phpunit/Event/Events/EventCollection.phpI��ÒVfgI��
  3011. Â�Ȥ������0���phpunit/Event/Events/EventCollectionIterator.php¼��ÒVfg¼��¶x¼ô¤������7���phpunit/Event/Events/Test/Assertion/AssertionFailed.php§��ÒVfg§��°Ô5â¤������A���phpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.phpH��ÒVfgH��òVî<¤������:���phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php­��ÒVfg­��Ì“îФ������D���phpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.phpN��ÒVfgN��Íû¢c¤������2���phpunit/Event/Events/Test/ComparatorRegistered.php
  3012. ��ÒVfg
  3013. ��§·Za¤������<���phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php@��ÒVfg@��Ú­êö¤������B���phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.phpi��ÒVfgi��“d¶¤������L���phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.phpJ��ÒVfgJ��‘Éü ¤������D���phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php`��ÒVfg`���Ó@”¤������N���phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.phpN��ÒVfgN��wœàK¤������>���phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php`��ÒVfg`��‡ñÀ7¤������H���phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.phpB��ÒVfgB��£R‘ÿ¤������@���phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.phpW��ÒVfgW��àþS÷¤������J���phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.phpF��ÒVfgF��–^‰_¤������D���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.phpm��ÒVfgm��\颤������N���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.phpN��ÒVfgN��eÚäu¤������E���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.phpõ��ÒVfgõ��ÈzÚc¤������O���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.phpP��ÒVfgP��ñ¨¥²¤������F���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.phpd��ÒVfgd��X'ªÅ¤������P���phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.phpR��ÒVfgR��½Á“\¤������?���phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.phpb��ÒVfgb��~�ò¤������I���phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.phpD��ÒVfgD��¿þƾ¤������A���phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.phpY��ÒVfgY��%‚'¤������K���phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.phpH��ÒVfgH��x—ŠS¤������<���phpunit/Event/Events/Test/HookMethod/PostConditionCalled.phpb��ÒVfgb��ò<ë¤������F���phpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php>��ÒVfg>��b*¤������>���phpunit/Event/Events/Test/HookMethod/PostConditionFinished.phpY��ÒVfgY��þwÜ:¤������H���phpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.phpB��ÒVfgB��WXF“¤������;���phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php`��ÒVfg`��áñ F¤������E���phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php<��ÒVfg<��u8O&¤������=���phpunit/Event/Events/Test/HookMethod/PreConditionFinished.phpW��ÒVfgW��)/Iy¤������G���phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php@��ÒVfg@��¡µX¤������3���phpunit/Event/Events/Test/Issue/ConsideredRisky.phpî��ÒVfgî��"­Ã¤������=���phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php6��ÒVfg6��S%LT¤������8���phpunit/Event/Events/Test/Issue/DeprecationTriggered.php ��ÒVfg ��9ƺ¤������B���phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php@��ÒVfg@��ö†“¤������2���phpunit/Event/Events/Test/Issue/ErrorTriggered.phpw ��ÒVfgw ��øòÎö¤������<���phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php4��ÒVfg4��R¹Â5¤������3���phpunit/Event/Events/Test/Issue/NoticeTriggered.phpõ
  3014. ��ÒVfgõ
  3015. ��Ÿ‹Ð¤������=���phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php6��ÒVfg6��'T$ž¤������;���phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php ��ÒVfg ��£*Ûà¤������E���phpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.phpF��ÒVfgF��ˆs†¤������6���phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.phpü
  3016. ��ÒVfgü
  3017. ���n`¤������@���phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php<��ÒVfg<���M¥s¤������7���phpunit/Event/Events/Test/Issue/PhpWarningTriggered.phpþ
  3018. ��ÒVfgþ
  3019. ��dD»œ¤������A���phpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php>��ÒVfg>��«
  3020. d¤������?���phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.phpd��ÒVfgd��èÅín¤������I���phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.phpN��ÒVfgN��lp®¤������9���phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.phpq��ÒVfgq��'0c¤������C���phpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.phpB��ÒVfgB��°Ÿ³;¤������;���phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php\��ÒVfg\���g’.¤������E���phpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.phpF��ÒVfgF���¶²â¤������4���phpunit/Event/Events/Test/Issue/WarningTriggered.php÷
  3021. ��ÒVfg÷
  3022. ��,ᢤ������>���phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php8��ÒVfg8��£®Z{¤������@���phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php.��ÒVfg.��bj}Z¤������J���phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.phpH��ÒVfgH��ë~-r¤������B���phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php ��ÒVfg ��£®£K¤������L���phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.phpL��ÒVfgL�� Ç?�¤������0���phpunit/Event/Events/Test/Lifecycle/Finished.phpw��ÒVfgw��u=6y¤������:���phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php(��ÒVfg(��.͵P¤������9���phpunit/Event/Events/Test/Lifecycle/PreparationFailed.phpp��ÒVfgp��´3&-¤������C���phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php:��ÒVfg:��ØÌ"»¤������:���phpunit/Event/Events/Test/Lifecycle/PreparationStarted.phpr��ÒVfgr��_ž¤������D���phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php<��ÒVfg<��&Uep¤������0���phpunit/Event/Events/Test/Lifecycle/Prepared.php]��ÒVfg]��qŠ­}¤������:���phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php(��ÒVfg(��ħK”¤������-���phpunit/Event/Events/Test/Outcome/Errored.phpú��ÒVfgú��é“@Þ¤������7���phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php&��ÒVfg&��èd3¤������,���phpunit/Event/Events/Test/Outcome/Failed.php¨��ÒVfg¨��Ef¥É¤������6���phpunit/Event/Events/Test/Outcome/FailedSubscriber.php$��ÒVfg$��À\*¤������6���phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php ��ÒVfg ��ªGEϤ������@���phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php8��ÒVfg8��
  3023. 6‹¤������,���phpunit/Event/Events/Test/Outcome/Passed.phpY��ÒVfgY��³Çõ^¤������6���phpunit/Event/Events/Test/Outcome/PassedSubscriber.php$��ÒVfg$��ÂÐ:y¤������-���phpunit/Event/Events/Test/Outcome/Skipped.php���ÒVfg���Wç¤������7���phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php&��ÒVfg&��{ªdz¤������5���phpunit/Event/Events/Test/PrintedUnexpectedOutput.php%��ÒVfg%��=P›Ÿ¤������?���phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.phpF��ÒVfgF��¾4¾­¤������:���phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php��ÒVfg��*®~é¤������D���phpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php:��ÒVfg:��E¨'á¤������J���phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php��ÒVfg��/bL¤������T���phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.phpZ��ÒVfgZ��Ü*�¤������U���phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.phpU��ÒVfgU��·Ùd¤������_���phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.phpp��ÒVfgp��-¤������B���phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php ��ÒVfg ��™–[‹¤������L���phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.phpJ��ÒVfgJ��~ÇH ¤������B���phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php
  3024. ��ÒVfg
  3025. ��²ìPޤ������L���phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.phpJ��ÒVfgJ��¬Žöͤ������A���phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php9��ÒVfg9��ˆRgä������K���phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.phpH��ÒVfgH��øþ¡£¤������9���phpunit/Event/Events/Test/TestDouble/TestProxyCreated.phpü��ÒVfgü��ªÏ¤������C���phpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php8��ÒVfg8��4ŒË¤������8���phpunit/Event/Events/Test/TestDouble/TestStubCreated.phpõ��ÒVfgõ�� 0«¤������B���phpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php6��ÒVfg6��íà ¤������S���phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.phpQ��ÒVfgQ��#…ð�¤������]���phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.phpl��ÒVfgl��ŠªR¤������5���phpunit/Event/Events/TestRunner/BootstrapFinished.phpf��ÒVfgf��J½¸¤������?���phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.phpF��ÒVfgF��€2¸=¤������.���phpunit/Event/Events/TestRunner/Configured.phpz��ÒVfgz��r³w8¤������8���phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php8��ÒVfg8��ÍL¿Ï¤������8���phpunit/Event/Events/TestRunner/DeprecationTriggered.phpq��ÒVfgq��ž o~¤������B���phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.phpL��ÒVfgL��öñ`2¤������5���phpunit/Event/Events/TestRunner/EventFacadeSealed.php���ÒVfg���ûj¤Z¤������?���phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.phpF��ÒVfgF��$¬v^¤������4���phpunit/Event/Events/TestRunner/ExecutionAborted.phpŠ��ÒVfgŠ��¿pÀ¿¤������>���phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.phpD��ÒVfgD��²sl|¤������5���phpunit/Event/Events/TestRunner/ExecutionFinished.phpŒ��ÒVfgŒ��J‚lM¤������?���phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.phpF��ÒVfgF���Ó¾ñ¤������4���phpunit/Event/Events/TestRunner/ExecutionStarted.phpã��ÒVfgã��³µfn¤������>���phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.phpD��ÒVfgD��ÿ.¤������9���phpunit/Event/Events/TestRunner/ExtensionBootstrapped.phpu��ÒVfgu��@*Ñÿ¤������C���phpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.phpN��ÒVfgN��Ã¥³¤������;���phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.phpÇ��ÒVfgÇ��ü¿&O¤������E���phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.phpR��ÒVfgR��A‹Æ¾¤������,���phpunit/Event/Events/TestRunner/Finished.phpy��ÒVfgy��Ôá¤������6���phpunit/Event/Events/TestRunner/FinishedSubscriber.php4��ÒVfg4��[Ixé¤������=���phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php���ÒVfg���w‹´¤������G���phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.phpV��ÒVfgV��y ÃW¤������<���phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php›��ÒVfg›��aá'Ö¤������F���phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.phpT��ÒVfgT��yÄ
  3026. ¤������>���phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.phpŸ��ÒVfgŸ��ƒjq¤������H���phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.phpX��ÒVfgX��€Jz¤������+���phpunit/Event/Events/TestRunner/Started.phpw��ÒVfgw��0ñt¤������5���phpunit/Event/Events/TestRunner/StartedSubscriber.php2��ÒVfg2��}ÃRp¤������4���phpunit/Event/Events/TestRunner/WarningTriggered.phpi��ÒVfgi��b�Ûü¤������>���phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.phpD��ÒVfgD��ʉú±¤������+���phpunit/Event/Events/TestSuite/Filtered.phpô��ÒVfgô��8¥T¤������5���phpunit/Event/Events/TestSuite/FilteredSubscriber.php2��ÒVfg2��™?¾Ë¤������+���phpunit/Event/Events/TestSuite/Finished.php��ÒVfg��~èH¤������5���phpunit/Event/Events/TestSuite/FinishedSubscriber.php2��ÒVfg2��JVˆ8¤������)���phpunit/Event/Events/TestSuite/Loaded.phpð��ÒVfgð��˜‡Uð¤������3���phpunit/Event/Events/TestSuite/LoadedSubscriber.php.��ÒVfg.��˜š)¤������*���phpunit/Event/Events/TestSuite/Skipped.php}��ÒVfg}���[}¤������4���phpunit/Event/Events/TestSuite/SkippedSubscriber.php0��ÒVfg0��èǤ������)���phpunit/Event/Events/TestSuite/Sorted.php"��ÒVfg"��:ä^‚¤������3���phpunit/Event/Events/TestSuite/SortedSubscriber.php.��ÒVfg.��ÝIN"¤������*���phpunit/Event/Events/TestSuite/Started.php��ÒVfg��Ã`Ó}¤������4���phpunit/Event/Events/TestSuite/StartedSubscriber.php0��ÒVfg0��¿Ý.¤������9���phpunit/Event/Exception/EventAlreadyAssignedException.php ��ÒVfg ��0•ɤ������8���phpunit/Event/Exception/EventFacadeIsSealedException.php
  3027. ��ÒVfg
  3028. ��J ؤ������%���phpunit/Event/Exception/Exception.phpL��ÒVfgL��gxº¤������4���phpunit/Event/Exception/InvalidArgumentException.phpù��ÒVfgù��Û䀤������1���phpunit/Event/Exception/InvalidEventException.php��ÒVfg��E>¯¤������6���phpunit/Event/Exception/InvalidSubscriberException.php��ÒVfg��SÜg¤������$���phpunit/Event/Exception/MapError.phpö��ÒVfgö��Õ÷äR¤������G���phpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php0��ÒVfg0���R=¤������8���phpunit/Event/Exception/NoComparisonFailureException.php��ÒVfg��â{k ¤������>���phpunit/Event/Exception/NoDataSetFromDataProviderException.php'��ÒVfg'��@~à¤������8���phpunit/Event/Exception/NoPreviousThrowableException.php
  3029. ��ÒVfg
  3030. ��Ùú¦~¤������@���phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.phpù��ÒVfgù��xs§Ù¤������,���phpunit/Event/Exception/RuntimeException.phpé��ÒVfgé��LÆ�¤������D���phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php��ÒVfg��į¨K¤������1���phpunit/Event/Exception/UnknownEventException.php��ÒVfg��šÜ}ê¤������5���phpunit/Event/Exception/UnknownEventTypeException.php��ÒVfg��/<ˆ¡¤������6���phpunit/Event/Exception/UnknownSubscriberException.php��ÒVfg�� ²Éˤ������:���phpunit/Event/Exception/UnknownSubscriberTypeException.php ��ÒVfg ��&'ý*¤���������phpunit/Event/Facade.phpò!��ÒVfgò!��é@©¥¤���������phpunit/Event/Subscriber.php£��ÒVfg£��dlkû¤���������phpunit/Event/Tracer.phpî��ÒVfgî��€Úm¤���������phpunit/Event/TypeMap.php—��ÒVfg—��ü`�¥¤������#���phpunit/Event/Value/ClassMethod.php™��ÒVfg™���@Õ¤������)���phpunit/Event/Value/ComparisonFailure.phpã��ÒVfgã��í‰ù…¤������0���phpunit/Event/Value/ComparisonFailureBuilder.phpM��ÒVfgM��ÀO”|¤������/���phpunit/Event/Value/Runtime/OperatingSystem.php±��ÒVfg±��‰Sᛤ������#���phpunit/Event/Value/Runtime/PHP.php ��ÒVfg ��@¬h¾¤������'���phpunit/Event/Value/Runtime/PHPUnit.phpm��ÒVfgm��þÇ«¤������'���phpunit/Event/Value/Runtime/Runtime.phpÌ��ÒVfgÌ��5lý¤������*���phpunit/Event/Value/Telemetry/Duration.phpÎ ��ÒVfgÎ ��Þ8žN¤������8���phpunit/Event/Value/Telemetry/GarbageCollectorStatus.phpJ��ÒVfgJ��¶}ù¤������@���phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.phpp��ÒVfgp��r Ù¤������(���phpunit/Event/Value/Telemetry/HRTime.phpŸ ��ÒVfgŸ ��l!ˆ¤������&���phpunit/Event/Value/Telemetry/Info.php§
  3031. ��ÒVfg§
  3032. ��LÌWh¤������-���phpunit/Event/Value/Telemetry/MemoryMeter.php¤��ÒVfg¤��'ìä}¤������-���phpunit/Event/Value/Telemetry/MemoryUsage.phpd��ÒVfgd��ƒýÞ÷¤������E���phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.phpÕ��ÒVfgÕ��<~ñ¤������E���phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.phpH��ÒVfgH��í± <¤������*���phpunit/Event/Value/Telemetry/Snapshot.php¦��ÒVfg¦��^r¤¤������+���phpunit/Event/Value/Telemetry/StopWatch.phpL��ÒVfgL��QØ¡6¤������(���phpunit/Event/Value/Telemetry/System.php§��ÒVfg§�� §95¤������3���phpunit/Event/Value/Telemetry/SystemMemoryMeter.phpè��ÒVfgè��5Åt±¤������1���phpunit/Event/Value/Telemetry/SystemStopWatch.phpZ��ÒVfgZ��@³ßj¤������;���phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php½��ÒVfg½��‹'^L¤������!���phpunit/Event/Value/Test/Phpt.php]��ÒVfg]��2›è©¤������!���phpunit/Event/Value/Test/Test.phpó��ÒVfgó��Î¥8‡¤������+���phpunit/Event/Value/Test/TestCollection.php-��ÒVfg-��å¯ü¤������3���phpunit/Event/Value/Test/TestCollectionIterator.phpÀ��ÒVfgÀ��q×ÿˤ������:���phpunit/Event/Value/Test/TestData/DataFromDataProvider.php��ÒVfg��þ¹}¤������<���phpunit/Event/Value/Test/TestData/DataFromTestDependency.php÷��ÒVfg÷��U¢ï»¤������.���phpunit/Event/Value/Test/TestData/TestData.phpÆ��ÒVfgÆ��#öé#¤������8���phpunit/Event/Value/Test/TestData/TestDataCollection.php›
  3033. ��ÒVfg›
  3034. ��oAõѤ������@���phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.phpÚ��ÒVfgÚ��Ô-ûK¤������$���phpunit/Event/Value/Test/TestDox.php
  3035. ��ÒVfg
  3036. ��ú%Ÿ–¤������+���phpunit/Event/Value/Test/TestDoxBuilder.phpB��ÒVfgB��^þÏü¤������'���phpunit/Event/Value/Test/TestMethod.php
  3037. ��ÒVfg
  3038. ��Ä.~¤������.���phpunit/Event/Value/Test/TestMethodBuilder.php ��ÒVfg ��7*K#¤������+���phpunit/Event/Value/TestSuite/TestSuite.php‚��ÒVfg‚��›GÔó¤������2���phpunit/Event/Value/TestSuite/TestSuiteBuilder.phpâ ��ÒVfgâ ��Τl¤������7���phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php¨��ÒVfg¨��Ïh~ã¤������H���phpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.phpz��ÒVfgz��qSUy¤������3���phpunit/Event/Value/TestSuite/TestSuiteWithName.php†��ÒVfg†��cmŸy¤������!���phpunit/Event/Value/Throwable.phpX ��ÒVfgX ��_S[y¤������(���phpunit/Event/Value/ThrowableBuilder.phpx��ÒVfgx��ö‘B¤���������phpunit/Exception.phpL��ÒVfgL��ù¨ßФ���������phpunit/Framework/Assert.phpÀý��ÒVfgÀý��w�S±¤������&���phpunit/Framework/Assert/Functions.php¨Z�ÒVfg¨Z�­¹s�¤������&���phpunit/Framework/Attributes/After.phpü��ÒVfgü��~jL¤������+���phpunit/Framework/Attributes/AfterClass.php��ÒVfg��˜³×ޤ������.���phpunit/Framework/Attributes/BackupGlobals.phpï��ÒVfgï��Òí<ߤ������7���phpunit/Framework/Attributes/BackupStaticProperties.phpø��ÒVfgø��ç³Õ¤������'���phpunit/Framework/Attributes/Before.phpý��ÒVfgý��ŸØ;¤������,���phpunit/Framework/Attributes/BeforeClass.php��ÒVfg��™…É\¤������3���phpunit/Framework/Attributes/CodeCoverageIgnore.phpn��ÒVfgn��pñwü¤������,���phpunit/Framework/Attributes/CoversClass.phpœ��ÒVfgœ��Óô-ʤ������/���phpunit/Framework/Attributes/CoversFunction.phpÀ��ÒVfgÀ��u•
  3039. ¢¤������.���phpunit/Framework/Attributes/CoversNothing.php��ÒVfg��&Þ�­¤������-���phpunit/Framework/Attributes/DataProvider.php±��ÒVfg±��sˆ\C¤������5���phpunit/Framework/Attributes/DataProviderExternal.phpý��ÒVfgý��‚i ù¤������(���phpunit/Framework/Attributes/Depends.php¬��ÒVfg¬��4ZR¤������0���phpunit/Framework/Attributes/DependsExternal.phpø��ÒVfgø��ÂÔ­|¤������>���phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php��ÒVfg��zâª�¤������A���phpunit/Framework/Attributes/DependsExternalUsingShallowClone.php ��ÒVfg ��K b ¤������/���phpunit/Framework/Attributes/DependsOnClass.php ��ÒVfg ��%*ŠB¤������=���phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php®��ÒVfg®��E2÷ã¤������@���phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php±��ÒVfg±��†±#Y¤������6���phpunit/Framework/Attributes/DependsUsingDeepClone.phpº��ÒVfgº��$àBv¤������9���phpunit/Framework/Attributes/DependsUsingShallowClone.php½��ÒVfg½��},Fm¤������9���phpunit/Framework/Attributes/DoesNotPerformAssertions.php)��ÒVfg)��¶J.~¤������@���phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php��ÒVfg��@¸7ò¤������@���phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php0��ÒVfg0��Hláp¤������&���phpunit/Framework/Attributes/Group.phpš��ÒVfgš��Qߤ������;���phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.phpö��ÒVfgö��:¿š¤������3���phpunit/Framework/Attributes/IgnoreDeprecations.php#��ÒVfg#��]ûeï¤������>���phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php��ÒVfg��´Ó�1¤������<���phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.phpN��ÒVfgN��»æ¤������&���phpunit/Framework/Attributes/Large.phpû��ÒVfgû��"mÓn¤������'���phpunit/Framework/Attributes/Medium.phpü��ÒVfgü��'þ2±¤������.���phpunit/Framework/Attributes/PostCondition.php��ÒVfg��Kƒ—¤������-���phpunit/Framework/Attributes/PreCondition.php��ÒVfg��Ø•ö@¤������4���phpunit/Framework/Attributes/PreserveGlobalState.phpõ��ÒVfgõ��¿Á)Ÿ¤������1���phpunit/Framework/Attributes/RequiresFunction.phpÝ��ÒVfgÝ��42\¤������/���phpunit/Framework/Attributes/RequiresMethod.php��ÒVfg��~àfi¤������8���phpunit/Framework/Attributes/RequiresOperatingSystem.phpì��ÒVfgì��Aµa±¤������>���phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php��ÒVfg��J™v5¤������,���phpunit/Framework/Attributes/RequiresPhp.phpç��ÒVfgç��9g§e¤������5���phpunit/Framework/Attributes/RequiresPhpExtension.phpt��ÒVfgt��:hK¤������0���phpunit/Framework/Attributes/RequiresPhpunit.phpë��ÒVfgë��ÿÌ"¤������0���phpunit/Framework/Attributes/RequiresSetting.phpí��ÒVfgí��Ÿ˜è¤������:���phpunit/Framework/Attributes/RunClassInSeparateProcess.php��ÒVfg��ï:˜¤������5���phpunit/Framework/Attributes/RunInSeparateProcess.php ��ÒVfg ��œ¤������<���phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php��ÒVfg��Úγ¤������&���phpunit/Framework/Attributes/Small.phpû��ÒVfgû��©w~‰¤������%���phpunit/Framework/Attributes/Test.phpû��ÒVfgû��Ã#¤������(���phpunit/Framework/Attributes/TestDox.php���ÒVfg���°2¤������)���phpunit/Framework/Attributes/TestWith.phpÜ��ÒVfgÜ��D¹ž6¤������-���phpunit/Framework/Attributes/TestWithJson.php‡��ÒVfg‡��‡¡ÁŸ¤������'���phpunit/Framework/Attributes/Ticket.php›��ÒVfg›��³Í™þ¤������*���phpunit/Framework/Attributes/UsesClass.phpš��ÒVfgš��ô 5¤������-���phpunit/Framework/Attributes/UsesFunction.php¾��ÒVfg¾��ýÍú¾¤������4���phpunit/Framework/Attributes/WithoutErrorHandler.php
  3040. ��ÒVfg
  3041. ��š�‚®¤������0���phpunit/Framework/Constraint/Boolean/IsFalse.php`��ÒVfg`��, µá¤������/���phpunit/Framework/Constraint/Boolean/IsTrue.php]��ÒVfg]��?6þͤ������)���phpunit/Framework/Constraint/Callback.php��ÒVfg��2¿¤������2���phpunit/Framework/Constraint/Cardinality/Count.php ��ÒVfg ��Fº…¤������8���phpunit/Framework/Constraint/Cardinality/GreaterThan.phpT��ÒVfgT��FdBI¤������4���phpunit/Framework/Constraint/Cardinality/IsEmpty.phpa��ÒVfga��q9ø¤������5���phpunit/Framework/Constraint/Cardinality/LessThan.phpN��ÒVfgN��C˜¤������5���phpunit/Framework/Constraint/Cardinality/SameSize.phpç��ÒVfgç��ÇBs¤������+���phpunit/Framework/Constraint/Constraint.phpÄ ��ÒVfgÄ ��¦úE¤������1���phpunit/Framework/Constraint/Equality/IsEqual.phpe ��ÒVfge ��£¿  ¤������?���phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php‹
  3042. ��ÒVfg‹
  3043. ��M+:}¤������=���phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php‘
  3044. ��ÒVfg‘
  3045. ��¡Ú“¤������:���phpunit/Framework/Constraint/Equality/IsEqualWithDelta.phpå ��ÒVfgå ��]Dž¤������4���phpunit/Framework/Constraint/Exception/Exception.phpß��ÒVfgß��°äv{¤������8���phpunit/Framework/Constraint/Exception/ExceptionCode.php>��ÒVfg>��r³Ú¤������G���phpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php$��ÒVfg$��x›¤ñ¤������S���phpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php·��ÒVfg·��7Ë«F¤������;���phpunit/Framework/Constraint/Filesystem/DirectoryExists.phpù��ÒVfgù��-pˆ¤������6���phpunit/Framework/Constraint/Filesystem/FileExists.phpô��ÒVfgô��ÿ+ð÷¤������6���phpunit/Framework/Constraint/Filesystem/IsReadable.phpô��ÒVfgô��“A†¤������6���phpunit/Framework/Constraint/Filesystem/IsWritable.phpô��ÒVfgô��öÆùB¤������+���phpunit/Framework/Constraint/IsAnything.php‰��ÒVfg‰��\ Òs¤������,���phpunit/Framework/Constraint/IsIdentical.php ��ÒVfg ��;j×K¤������,���phpunit/Framework/Constraint/JsonMatches.php
  3046. ��ÒVfg
  3047. ��Ðä*Q¤������.���phpunit/Framework/Constraint/Math/IsFinite.phpz��ÒVfgz��ÔŠø¤������0���phpunit/Framework/Constraint/Math/IsInfinite.php‚��ÒVfg‚��íC²¤������+���phpunit/Framework/Constraint/Math/IsNan.phpn��ÒVfgn��Ç�x¤������4���phpunit/Framework/Constraint/Object/ObjectEquals.phpq��ÒVfgq��Êj¢¤������9���phpunit/Framework/Constraint/Object/ObjectHasProperty.php��ÒVfg��"„¦Ç¤������8���phpunit/Framework/Constraint/Operator/BinaryOperator.phpV ��ÒVfgV ��©M
  3048. ¤������4���phpunit/Framework/Constraint/Operator/LogicalAnd.phpY��ÒVfgY��ÿ‡ý¤������4���phpunit/Framework/Constraint/Operator/LogicalNot.php8 ��ÒVfg8 ��ôü/¾¤������3���phpunit/Framework/Constraint/Operator/LogicalOr.php=��ÒVfg=��"iN¤������4���phpunit/Framework/Constraint/Operator/LogicalXor.php™��ÒVfg™��ø�¿Þ¤������2���phpunit/Framework/Constraint/Operator/Operator.php'��ÒVfg'��áJÂ%¤������7���phpunit/Framework/Constraint/Operator/UnaryOperator.php��ÒVfg��5D ¤������.���phpunit/Framework/Constraint/String/IsJson.phpÞ ��ÒVfgÞ ��ûQÐ]¤������9���phpunit/Framework/Constraint/String/RegularExpression.php^��ÒVfg^��ŠË¬>¤������6���phpunit/Framework/Constraint/String/StringContains.phpZ��ÒVfgZ��9kR¤������6���phpunit/Framework/Constraint/String/StringEndsWith.phpð��ÒVfgð��@%õ-¤������M���phpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php7��ÒVfg7��[…J¤������F���phpunit/Framework/Constraint/String/StringMatchesFormatDescription.phpó ��ÒVfgó ��µ'5a¤������8���phpunit/Framework/Constraint/String/StringStartsWith.phpø��ÒVfgø��™.ÿ¤������8���phpunit/Framework/Constraint/Traversable/ArrayHasKey.php~��ÒVfg~��â.€¾¤������3���phpunit/Framework/Constraint/Traversable/IsList.phpW��ÒVfgW��m×Fr¤������@���phpunit/Framework/Constraint/Traversable/TraversableContains.php|��ÒVfg|��Guìz¤������E���phpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php(��ÒVfg(��alr¤������I���phpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.phpî��ÒVfgî��ËÁg¤������D���phpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php`��ÒVfg`��ˆßl¤������2���phpunit/Framework/Constraint/Type/IsInstanceOf.phpÛ��ÒVfgÛ��áY³Û¤������,���phpunit/Framework/Constraint/Type/IsNull.php\��ÒVfg\��a#‡ ¤������,���phpunit/Framework/Constraint/Type/IsType.php���ÒVfg���[³j ¤������+���phpunit/Framework/DataProviderTestSuite.php;��ÒVfg;��ågE™¤������4���phpunit/Framework/Exception/AssertionFailedError.phpþ��ÒVfgþ��Ï5/¤������5���phpunit/Framework/Exception/CodeCoverageException.php/��ÒVfg/��9}‚¤������4���phpunit/Framework/Exception/EmptyStringException.phpC��ÒVfgC��‹ÖšÍ¤������)���phpunit/Framework/Exception/Exception.phpÿ ��ÒVfgÿ ��ÉÀ“¤������:���phpunit/Framework/Exception/ExpectationFailedException.php*��ÒVfg*��ûˆáÞ¤������>���phpunit/Framework/Exception/GeneratorNotSupportedException.php:��ÒVfg:��™ j{¤������9���phpunit/Framework/Exception/Incomplete/IncompleteTest.php(��ÒVfg(��KÉ9¤������>���phpunit/Framework/Exception/Incomplete/IncompleteTestError.phpk��ÒVfgk��÷›øè¤������8���phpunit/Framework/Exception/InvalidArgumentException.php;��ÒVfg;��÷ñ‹)¤������<���phpunit/Framework/Exception/InvalidCoversTargetException.phpH��ÒVfgH��„´›n¤������<���phpunit/Framework/Exception/InvalidDataProviderException.php<��ÒVfg<��tõH,¤������:���phpunit/Framework/Exception/InvalidDependencyException.phpo��ÒVfgo��i¾Ôí¤������9���phpunit/Framework/Exception/NoChildTestSuiteException.php9��ÒVfg9��4´Ý¤������N���phpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php­��ÒVfg­��·òW÷¤������`���phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.phpW��ÒVfgW��Œ‹–½¤������b���phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php>��ÒVfg>��{ý–�¤������g���phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.phpH��ÒVfgH��°t ²¤������a���phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.phpF��ÒVfgF��ñ †9¤������R���phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php��ÒVfg��Ý/]¤������8���phpunit/Framework/Exception/PhptAssertionFailedError.phpš��ÒVfgš��lj~ü¤������9���phpunit/Framework/Exception/ProcessIsolationException.php9��ÒVfg9��,ÿä������3���phpunit/Framework/Exception/Skipped/SkippedTest.php%��ÒVfg%��5há¤������=���phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.phpj��ÒVfgj��wÜŠ¤������C���phpunit/Framework/Exception/Skipped/SkippedWithMessageException.phpp��ÒVfgp��X&º>¤������@���phpunit/Framework/Exception/UnknownClassOrInterfaceException.phpö��ÒVfgö��H nw¤������4���phpunit/Framework/Exception/UnknownTypeException.phpÚ��ÒVfgÚ��‹�4¤������.���phpunit/Framework/ExecutionOrderDependency.php��ÒVfg���§[}¤������3���phpunit/Framework/MockObject/ConfigurableMethod.php>��ÒVfg>��gYL¤������A���phpunit/Framework/MockObject/Exception/BadMethodCallException.phpo��ÒVfgo��äÛ!�¤������H���phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.phpt��ÒVfgt��™¬
  3049. ¤������4���phpunit/Framework/MockObject/Exception/Exception.php.��ÒVfg.��‹p‚¤������K���phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.phpå��ÒVfgå��2íK]¤������H���phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php.��ÒVfg.��ú¤´a¤������L���phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php&��ÒVfg&��æÝ������L���phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.phpˆ��ÒVfgˆ��7À„3¤������O���phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.phpò��ÒVfgò��<Ú¬>¤������K���phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.phpê��ÒVfgê��ªYi¤������U���phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.phpû��ÒVfgû��¥s¤������H���phpunit/Framework/MockObject/Exception/NeverReturningMethodException.phpm��ÒVfgm��+"º¤������P���phpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php×��ÒVfg×��H]²ò¤������L���phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php¨��ÒVfg¨��2’×V¤������;���phpunit/Framework/MockObject/Exception/RuntimeException.phpc��ÒVfgc��õ€= ¤������Q���phpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.phpµ��ÒVfgµ��˜¬•¤������P���phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.phpJ��ÒVfgJ�� `@ ¤������J���phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.phpF��ÒVfgF��Ô�ƒ¤������M���phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.phpL��ÒVfgL��¿ã:u¤������M���phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.phpL��ÒVfgL��¯†…�¤������>���phpunit/Framework/MockObject/Generator/Exception/Exception.phpn��ÒVfgn��½q~•¤������O���phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php<��ÒVfg<��×ÓªÙ¤������N���phpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.phpo��ÒVfgo��ü¡ë¤������c���phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php6��ÒVfg6��@QbÖ¤������H���phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php…��ÒVfg…��"è¤������E���phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php‚��ÒVfg‚��„Ãø¤������W���phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php%��ÒVfg%��NMé¤������J���phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php+��ÒVfg+��Àò»“¤������J���phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.phpv��ÒVfgv��Kˆß¤������I���phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php-��ÒVfg-���¨‰V¤������4���phpunit/Framework/MockObject/Generator/Generator.phpz~��ÒVfgz~��
  3050. {ÁV¤������4���phpunit/Framework/MockObject/Generator/MockClass.phpÎ��ÒVfgÎ��¶D ç¤������5���phpunit/Framework/MockObject/Generator/MockMethod.php¿*��ÒVfg¿*��_SV£¤������8���phpunit/Framework/MockObject/Generator/MockMethodSet.phpÚ��ÒVfgÚ��K¹Bˤ������4���phpunit/Framework/MockObject/Generator/MockTrait.phpú��ÒVfgú��qQ¼Y¤������3���phpunit/Framework/MockObject/Generator/MockType.phpp��ÒVfgp��RΟ¤������9���phpunit/Framework/MockObject/Generator/TemplateLoader.php��ÒVfg��°ý�¤������@���phpunit/Framework/MockObject/Generator/templates/deprecation.tpl;���ÒVfg;���O5øs¤������C���phpunit/Framework/MockObject/Generator/templates/doubled_method.tplV��ÒVfgV��šè%¤������J���phpunit/Framework/MockObject/Generator/templates/doubled_static_method.tplî���ÒVfgî��� 4éR¤������A���phpunit/Framework/MockObject/Generator/templates/intersection.tplL���ÒVfgL���®Ž-X¤������C���phpunit/Framework/MockObject/Generator/templates/proxied_method.tplš��ÒVfgš��œ ¢¤������F���phpunit/Framework/MockObject/Generator/templates/test_double_class.tplf���ÒVfgf���'­í ¤������@���phpunit/Framework/MockObject/Generator/templates/trait_class.tplQ���ÒVfgQ���÷<‹È¤������?���phpunit/Framework/MockObject/Generator/templates/wsdl_class.tplÍ���ÒVfgÍ���ô’±¤������@���phpunit/Framework/MockObject/Generator/templates/wsdl_method.tpl<���ÒVfg<���¾Ði‰¤������,���phpunit/Framework/MockObject/MockBuilder.phpâ/��ÒVfgâ/��MJ¬°¤������?���phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php���ÒVfg���ê%ný¤������3���phpunit/Framework/MockObject/Runtime/Api/Method.phpx��ÒVfgx��2`™Ç¤������:���phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.phpã��ÒVfgã��”�i�¤������?���phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php¸��ÒVfg¸��ûcùô¤������4���phpunit/Framework/MockObject/Runtime/Api/StubApi.php���ÒVfg���Ù™¤������9���phpunit/Framework/MockObject/Runtime/Builder/Identity.phpÆ��ÒVfgÆ���õ ¤������A���phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.phpþ"��ÒVfgþ"��5†ý‡¤������B���phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php¢��ÒVfg¢��¾(†I¤������@���phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.phpM��ÒVfgM��í¯Ù�¤������@���phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php·��ÒVfg·��9ä"ï¤������5���phpunit/Framework/MockObject/Runtime/Builder/Stub.php|��ÒVfg|��“õRµ¤������=���phpunit/Framework/MockObject/Runtime/Interface/MockObject.phpÒ��ÒVfgÒ��mˆOé¤������E���phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.phpJ��ÒVfgJ�� 3˜ ¤������7���phpunit/Framework/MockObject/Runtime/Interface/Stub.php��ÒVfg��©liH¤������?���phpunit/Framework/MockObject/Runtime/Interface/StubInternal.phpÌ��ÒVfgÌ��š$'¤������3���phpunit/Framework/MockObject/Runtime/Invocation.phpB��ÒVfgB��é\¤¤������:���phpunit/Framework/MockObject/Runtime/InvocationHandler.php��ÒVfg��êÕ4�¤������0���phpunit/Framework/MockObject/Runtime/Matcher.php��ÒVfg��D>F¤������=���phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php��ÒVfg��Hç ¤������=���phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php��ÒVfg��õ�s¤������=���phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.phpƒ��ÒVfgƒ��/d²k¤������;���phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php ��ÒVfg ��pìÛ"¤������=���phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php=��ÒVfg=��hñ¹¤������A���phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php*��ÒVfg*��䙆³¤������@���phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.phpG��ÒVfgG��ãfËs¤������@���phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php��ÒVfg��yÃIޤ������:���phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.phpÁ ��ÒVfgÁ �� I¤������8���phpunit/Framework/MockObject/Runtime/Rule/MethodName.php{��ÒVfg{��8 ù¤������8���phpunit/Framework/MockObject/Runtime/Rule/Parameters.php”��ÒVfg”��´ÕVJ¤������<���phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.phpë��ÒVfgë��v®Y¤������>���phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.phpÅ��ÒVfgÅ��‚µjY¤������7���phpunit/Framework/MockObject/Runtime/Stub/Exception.php¦��ÒVfg¦��ŸfaŸ¤������<���phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.phpŸ��ÒVfgŸ��^˜¤������<���phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.phpÔ��ÒVfgÔ��2à¶Q¤������=���phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.phpf��ÒVfgf��¦ÿ¬Ó¤������8���phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.phpE��ÒVfgE��“”DѤ������8���phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.phpT��ÒVfgT��øBO¤������<���phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php��ÒVfg��…WŠì¤������2���phpunit/Framework/MockObject/Runtime/Stub/Stub.phpå��ÒVfgå��ïÿ̶¤������!���phpunit/Framework/Reorderable.php���ÒVfg���§ßH¹¤������$���phpunit/Framework/SelfDescribing.phpu��ÒVfgu��ú¤���������phpunit/Framework/Test.phpã��ÒVfgã��­�ñ9¤������!���phpunit/Framework/TestBuilder.php°'��ÒVfg°'��Jh£e¤���������phpunit/Framework/TestCase.php+ �ÒVfg+ �ònJ ¤������ ���phpunit/Framework/TestRunner.phpä7��ÒVfgä7��ºk�é¤������$���phpunit/Framework/TestSize/Known.php��ÒVfg��Æ~¤������$���phpunit/Framework/TestSize/Large.php˜��ÒVfg˜��®Ù§1¤������%���phpunit/Framework/TestSize/Medium.php›��ÒVfg›��«2Jì¤������$���phpunit/Framework/TestSize/Small.phpŒ��ÒVfgŒ��sÐ%j¤������'���phpunit/Framework/TestSize/TestSize.php—��ÒVfg—��†Œqû¤������&���phpunit/Framework/TestSize/Unknown.php��ÒVfg��Š !�¤������,���phpunit/Framework/TestStatus/Deprecation.phpo��ÒVfgo��'šëK¤������&���phpunit/Framework/TestStatus/Error.phpW��ÒVfgW��YÜs¹¤������(���phpunit/Framework/TestStatus/Failure.php_��ÒVfg_��<%�J¤������+���phpunit/Framework/TestStatus/Incomplete.phpk��ÒVfgk��„Ï�̤������&���phpunit/Framework/TestStatus/Known.phpÕ��ÒVfgÕ���ŠZˤ������'���phpunit/Framework/TestStatus/Notice.php[��ÒVfg[��—òV¤������&���phpunit/Framework/TestStatus/Risky.phpW��ÒVfgW��‚…6¯¤������(���phpunit/Framework/TestStatus/Skipped.php_��ÒVfg_��L„æ#¤������(���phpunit/Framework/TestStatus/Success.php_��ÒVfg_��}Êɤ������+���phpunit/Framework/TestStatus/TestStatus.php°��ÒVfg°��âɪi¤������(���phpunit/Framework/TestStatus/Unknown.phpe��ÒVfge��Ãe&¤������(���phpunit/Framework/TestStatus/Warning.php_��ÒVfg_��3°D‰¤���������phpunit/Framework/TestSuite.php-G��ÒVfg-G��È‹$¤������'���phpunit/Framework/TestSuiteIterator.php˜��ÒVfg˜��4g–[¤���������phpunit/Logging/EventLogger.php��ÒVfg��–C8ؤ������(���phpunit/Logging/JUnit/JunitXmlLogger.phpÃ/��ÒVfgÃ/��Ëê&«¤������/���phpunit/Logging/JUnit/Subscriber/Subscriber.php=��ÒVfg=��_� ¤������:���phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.phpt��ÒVfgt��Ù{ñ¤������9���phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.phpn��ÒVfgn��P^Ôí¤������;���phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.phpz��ÒVfgz��ðèF¸¤������C���phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.phpª��ÒVfgª��  [¤������D���phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.phpª��ÒVfgª��Ð?Lö¤������E���phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php¶��ÒVfg¶��Ïxˆ¤������;���phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.phpt��ÒVfgt��hêt:¤������J���phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.phpH��ÒVfgH��Vï–¤������:���phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.phpt��ÒVfgt��P¥V¤������@���phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php$��ÒVfg$��;ÔB¤������?���phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php$��ÒVfg$��ì *¤������2���phpunit/Logging/TeamCity/Subscriber/Subscriber.phpI��ÒVfgI��íÛKѤ������E���phpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.phpª��ÒVfgª��‡—yݤ������=���phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.phpz��ÒVfgz��Ëû[¤������<���phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.phpt��ÒVfgt��˜Û²Á¤������>���phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php€��ÒVfg€��{�‡¤������F���phpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php°��ÒVfg°��аØ]¤������>���phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php��ÒVfg��¶Qz:¤������M���phpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.phpN��ÒVfgN��DIRâ¤������=���phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.phpz��ÒVfgz��è–¤������W���phpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.phpù��ÒVfgù��}�v�¤������C���phpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php0��ÒVfg0��_!€Ç¤������B���phpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.phpŽ��ÒVfgŽ��—Ôr¤������B���phpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php*��ÒVfg*��ãÙUî¤������+���phpunit/Logging/TeamCity/TeamCityLogger.phpt+��ÒVfgt+��å;9¤������(���phpunit/Logging/TestDox/HtmlRenderer.php*��ÒVfg*��[£òU¤������*���phpunit/Logging/TestDox/NamePrettifier.phpÙ!��ÒVfgÙ!��`˜#æ¤������-���phpunit/Logging/TestDox/PlainTextRenderer.php‡��ÒVfg‡��”*ïM¤������<���phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.phpf��ÒVfgf��.=¤������O���phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.phpG��ÒVfgG��ÖÝÓ¤������G���phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php��ÒVfg��ÎR¤������F���phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php��ÒVfg��ìÚpd¤������H���phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php���ÒVfg���CZhܤ������P���phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpM��ÒVfgM��EM�¤������F���phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php��ÒVfg��(+×%¤������H���phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php��ÒVfg��™>W&¤������G���phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php��ÒVfg��N85°¤������T���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpe��ÒVfge��ÄZ¼Û¤������O���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpG��ÒVfgG��™¨`¤������W���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpw��ÒVfgw��ÔÉv»¤������R���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpY��ÒVfgY��©Rؤ������S���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php_��ÒVfg_��öe¾í¤������[���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php���ÒVfg���( פ������U���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.phpk��ÒVfgk��\ê�¤������W���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpw��ÒVfgw��™'[ü¤������P���phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpM��ÒVfgM��9^é}¤������1���phpunit/Logging/TestDox/TestResult/TestResult.php|��ÒVfg|��P»«ó¤������;���phpunit/Logging/TestDox/TestResult/TestResultCollection.php~��ÒVfg~�� }¤������C���phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.phpm��ÒVfgm��ÿ»y¤������:���phpunit/Logging/TestDox/TestResult/TestResultCollector.phpt1��ÒVfgt1��ÒŠWÔ¤���������phpunit/Metadata/After.php\��ÒVfg\�� #ú¿¤���������phpunit/Metadata/AfterClass.phpk��ÒVfgk��†bÙ¤������%���phpunit/Metadata/Api/CodeCoverage.php&��ÒVfg&��±ëô›¤������%���phpunit/Metadata/Api/DataProvider.phpà!��ÒVfgà!��a*jê¤������%���phpunit/Metadata/Api/Dependencies.php‹��ÒVfg‹��A ö�¤���������phpunit/Metadata/Api/Groups.php��ÒVfg��Ę´¤������$���phpunit/Metadata/Api/HookMethods.phpß ��ÒVfgß ��Å5æ`¤������%���phpunit/Metadata/Api/Requirements.php;��ÒVfg;��æÕ�·¤������"���phpunit/Metadata/BackupGlobals.php¨��ÒVfg¨��-ñ5/¤������+���phpunit/Metadata/BackupStaticProperties.phpÃ��ÒVfgÃ��Š`/r¤���������phpunit/Metadata/Before.php_��ÒVfg_��ådݤ������ ���phpunit/Metadata/BeforeClass.phpn��ÒVfgn��)Mº ¤���������phpunit/Metadata/Covers.php)��ÒVfg)��l©¤������ ���phpunit/Metadata/CoversClass.php=��ÒVfg=��¯ß‚ê¤������'���phpunit/Metadata/CoversDefaultClass.phpV��ÒVfgV��0ã´ë¤������#���phpunit/Metadata/CoversFunction.phpH��ÒVfgH��`«¯&¤������"���phpunit/Metadata/CoversNothing.phpt��ÒVfgt��öΎǤ������!���phpunit/Metadata/DataProvider.php›��ÒVfg›��ûºÿ¤������#���phpunit/Metadata/DependsOnClass.php¾��ÒVfg¾��%š¡¤������$���phpunit/Metadata/DependsOnMethod.php��ÒVfg��à¿-¤������-���phpunit/Metadata/DoesNotPerformAssertions.php•��ÒVfg•��¸œ!¢¤������T���phpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php´��ÒVfg´��{Ûʉ¤������(���phpunit/Metadata/Exception/Exception.phpO��ÒVfgO��Ñw¥ö¤������A���phpunit/Metadata/Exception/InvalidVersionRequirementException.php¥��ÒVfg¥��PìR´¤������<���phpunit/Metadata/Exception/NoVersionRequirementException.php ��ÒVfg ��?+ç�¤������2���phpunit/Metadata/Exception/ReflectionException.phph��ÒVfgh��`´có¤������4���phpunit/Metadata/ExcludeGlobalVariableFromBackup.phpÈ��ÒVfgÈ��°ù­¤������4���phpunit/Metadata/ExcludeStaticPropertyFromBackup.phpâ��ÒVfgâ��×å0^¤���������phpunit/Metadata/Group.php;��ÒVfg;���A\§¤������/���phpunit/Metadata/IgnoreClassForCodeCoverage.php¹��ÒVfg¹��/Z�g¤������'���phpunit/Metadata/IgnoreDeprecations.phpƒ��ÒVfgƒ��?iÖW¤������2���phpunit/Metadata/IgnoreFunctionForCodeCoverage.phpã��ÒVfgã��*â¤������0���phpunit/Metadata/IgnoreMethodForCodeCoverage.php��ÒVfg��Q??¤���������phpunit/Metadata/Metadata.phpŠ[��ÒVfgŠ[��=ˆ)P¤������'���phpunit/Metadata/MetadataCollection.php.��ÒVfg.��Še¤ ¤������/���phpunit/Metadata/MetadataCollectionIterator.phpà��ÒVfgà��¦«î1¤������/���phpunit/Metadata/Parser/Annotation/DocBlock.phpÆ"��ÒVfgÆ"��àC�,¤������/���phpunit/Metadata/Parser/Annotation/Registry.phpê ��ÒVfgê ��…¯ú¤������,���phpunit/Metadata/Parser/AnnotationParser.phpH��ÒVfgH��HXkv¤������+���phpunit/Metadata/Parser/AttributeParser.phpÎY��ÒVfgÎY��.Ø—Ÿ¤������)���phpunit/Metadata/Parser/CachingParser.phpñ ��ÒVfgñ ��—??¤������"���phpunit/Metadata/Parser/Parser.phpE��ÒVfgE��á¦ñ°¤������'���phpunit/Metadata/Parser/ParserChain.php ��ÒVfg ��1•VÁ¤������$���phpunit/Metadata/Parser/Registry.php†��ÒVfg†��^†ûw¤������"���phpunit/Metadata/PostCondition.phpt��ÒVfgt��ÙÕ¾.¤������!���phpunit/Metadata/PreCondition.phpq��ÒVfgq��ˆõ�S¤������(���phpunit/Metadata/PreserveGlobalState.phpº��ÒVfgº��*odï¤������%���phpunit/Metadata/RequiresFunction.phpq��ÒVfgq��¡Žîÿ¤������#���phpunit/Metadata/RequiresMethod.php¡��ÒVfg¡��ë¾9¤������,���phpunit/Metadata/RequiresOperatingSystem.php˜��ÒVfg˜��cM)¹¤������2���phpunit/Metadata/RequiresOperatingSystemFamily.php×��ÒVfg×��IM-~¤������ ���phpunit/Metadata/RequiresPhp.php#��ÒVfg#��µîÐc¤������)���phpunit/Metadata/RequiresPhpExtension.php��ÒVfg��ð�÷q¤������$���phpunit/Metadata/RequiresPhpunit.php/��ÒVfg/��9D¤������$���phpunit/Metadata/RequiresSetting.php��ÒVfg��â¹åK¤������.���phpunit/Metadata/RunClassInSeparateProcess.php˜��ÒVfg˜��®mEã¤������)���phpunit/Metadata/RunInSeparateProcess.php‰��ÒVfg‰��à3ÃU¤������0���phpunit/Metadata/RunTestsInSeparateProcesses.phpž��ÒVfgž��”nùa¤���������phpunit/Metadata/Test.phpY��ÒVfgY��z7凤���������phpunit/Metadata/TestDox.php��ÒVfg��Ò�§3¤���������phpunit/Metadata/TestWith.phpŠ��ÒVfgŠ��W€üK¤���������phpunit/Metadata/Uses.php#��ÒVfg#��NœÃܤ���������phpunit/Metadata/UsesClass.php7��ÒVfg7��Ưéþ¤������%���phpunit/Metadata/UsesDefaultClass.phpP��ÒVfgP��øIC–¤������!���phpunit/Metadata/UsesFunction.php?��ÒVfg?���Â`&¤������2���phpunit/Metadata/Version/ComparisonRequirement.phpf��ÒVfgf��—Ή•¤������2���phpunit/Metadata/Version/ConstraintRequirement.php��ÒVfg��ËtúÒ¤������(���phpunit/Metadata/Version/Requirement.phpá��ÒVfgá��/ïs”¤������(���phpunit/Metadata/WithoutErrorHandler.php†��ÒVfg†��F=f¤������$���phpunit/Runner/Baseline/Baseline.phpe��ÒVfge��ø¾Éó¤������A���phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php~��ÒVfg~��=)Sb¤������B���phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php1��ÒVfg1��ü3€¤������%���phpunit/Runner/Baseline/Generator.phpç��ÒVfgç��Ä�¤������!���phpunit/Runner/Baseline/Issue.php§ ��ÒVfg§ ��šüÆ×¤������"���phpunit/Runner/Baseline/Reader.phpà ��ÒVfgà ��¯�ó-¤������2���phpunit/Runner/Baseline/RelativePathCalculator.php ��ÒVfg �� Gy6¤������1���phpunit/Runner/Baseline/Subscriber/Subscriber.phpH��ÒVfgH��±›åq¤������I���phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.phpò��ÒVfgò��;Õéä������D���phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.phpÙ��ÒVfgÙ��xOë*¤������L���phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php��ÒVfg��¯¯XM¤������G���phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.phpè��ÒVfgè���Zà¤������H���phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.phpí��ÒVfgí��±ž†Ö¤������E���phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.phpÞ��ÒVfgÞ��$§ÆD¤������"���phpunit/Runner/Baseline/Writer.phpþ��ÒVfgþ��R )±¤���������phpunit/Runner/CodeCoverage.phpŸ3��ÒVfgŸ3��-iL¤���������phpunit/Runner/ErrorHandler.php[��ÒVfg[��¤DÒ�¤������8���phpunit/Runner/Exception/ClassCannotBeFoundException.php%��ÒVfg%��uëX�¤������@���phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.phpQ��ÒVfgQ��κYÀ¤������5���phpunit/Runner/Exception/ClassIsAbstractException.php'��ÒVfg'��ƒìT¤������;���phpunit/Runner/Exception/DirectoryDoesNotExistException.php+��ÒVfg+��EH¾-¤������+���phpunit/Runner/Exception/ErrorException.phpD��ÒVfgD��i}Ť������&���phpunit/Runner/Exception/Exception.php��ÒVfg��V‚Õ•¤������6���phpunit/Runner/Exception/FileDoesNotExistException.phpþ��ÒVfgþ��dfH!¤������2���phpunit/Runner/Exception/InvalidOrderException.phpa��ÒVfga��[Èt%¤������5���phpunit/Runner/Exception/InvalidPhptFileException.phpd��ÒVfgd��N8 Ȥ������;���phpunit/Runner/Exception/ParameterDoesNotExistException.php��ÒVfg��Z­Ÿh¤������D���phpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.phpC��ÒVfgC��þÔUr¤������<���phpunit/Runner/Exception/UnsupportedPhptSectionException.php��ÒVfg��Ä¡·§¤������&���phpunit/Runner/Extension/Extension.php…��ÒVfg…��sƲ¤������2���phpunit/Runner/Extension/ExtensionBootstrapper.phpØ ��ÒVfgØ ��ö¦c�¤������#���phpunit/Runner/Extension/Facade.phpé
  3051. ��ÒVfgé
  3052. ��Ï~hؤ������0���phpunit/Runner/Extension/ParameterCollection.phpæ��ÒVfgæ��P›|¤������'���phpunit/Runner/Extension/PharLoader.php(��ÒVfg(��’²Ý ¤������4���phpunit/Runner/Filter/ExcludeGroupFilterIterator.php×��ÒVfg×��nñ$¤������!���phpunit/Runner/Filter/Factory.php1��ÒVfg1��ÍñØE¤������-���phpunit/Runner/Filter/GroupFilterIterator.php£��ÒVfg£��|už]¤������4���phpunit/Runner/Filter/IncludeGroupFilterIterator.phpÖ��ÒVfgÖ��liФ������,���phpunit/Runner/Filter/NameFilterIterator.phpÍ ��ÒVfgÍ ��Å;D+¤������.���phpunit/Runner/Filter/TestIdFilterIterator.php+��ÒVfg+��2ñöK¤������=���phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php6 ��ÒVfg6 ��&%à�¤������K���phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php3��ÒVfg3��9»t¤������J���phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php,��ÒVfg,��ÖFÉç¤������:���phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php���ÒVfg���ç1XK¤������F���phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.phpÆ��ÒVfgÆ��²¥À£¤���������phpunit/Runner/PhptTestCase.phpÜU��ÒVfgÜU��sWœÙ¤������1���phpunit/Runner/ResultCache/DefaultResultCache.php€��ÒVfg€��@pF.¤������.���phpunit/Runner/ResultCache/NullResultCache.php��ÒVfg��V»õø¤������*���phpunit/Runner/ResultCache/ResultCache.phpc��ÒVfgc��B3ÖÖ¤������1���phpunit/Runner/ResultCache/ResultCacheHandler.php��ÒVfg��ë 0õ¤������4���phpunit/Runner/ResultCache/Subscriber/Subscriber.phpc��ÒVfgc��éhäz¤������G���phpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.phpK��ÒVfgK��+ö²+¤������?���phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php��ÒVfg��†Ÿ¤������>���phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php��ÒVfg��\´Yn¤������@���phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.phpÀ��ÒVfgÀ��ÈFÐ ¤������H���phpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.phpQ��ÒVfgQ�� :Ý¢¤������@���phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php!��ÒVfg!��†°E¤������?���phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.phpº��ÒVfgº��ÌÛN¤������E���phpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php/��ÒVfg/��¨·>¤������D���phpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php)��ÒVfg)��Æ”p¤������'���phpunit/Runner/TestResult/Collector.phpkI��ÒVfgkI��!¡Ã8¤������$���phpunit/Runner/TestResult/Facade.phpð ��ÒVfgð ��¹Ö®¤������#���phpunit/Runner/TestResult/Issue.phpK
  3053. ��ÒVfgK
  3054. ��If¤������)���phpunit/Runner/TestResult/PassedTests.phpˆ ��ÒVfgˆ ��š(æ[¤������O���phpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php™��ÒVfg™��sÂc¤������C���phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php���ÒVfg���0ÍRœ¤������3���phpunit/Runner/TestResult/Subscriber/Subscriber.php`��ÒVfg`��z۩ɤ������F���phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.phpS��ÒVfgS��pZX"¤������>���phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php#��ÒVfg#��œùÎ.¤������=���phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php��ÒVfg��¦1qù¤������?���phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php)��ÒVfg)��J¶p¤������G���phpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpY��ÒVfgY��Àcz¤������?���phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php#��ÒVfg#��$ÛÆU¤������Q���phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php‰��ÒVfg‰��Î,Ѥ������M���phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.phpq��ÒVfgq��K¸Œ¿¤������>���phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php#��ÒVfg#��‰Yº¤������D���phpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php=��ÒVfg=��»„¼¤������C���phpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php7��ÒVfg7��W£•¤������C���phpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php7��ÒVfg7��')ܤ������K���phpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpq��ÒVfgq��ŠkÝx¤������E���phpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.phpM��ÒVfgM��/^éÚ¤������F���phpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpS��ÒVfgS��Ø`¤������N���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpƒ��ÒVfgƒ��IE&¤������I���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpe��ÒVfge��¢Z³¢¤������J���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.phpk��ÒVfgk��‹)Ïe¤������R���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php›��ÒVfg›��TkG¤������L���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.phpw��ÒVfgw��;NÅQ¤������N���phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpƒ��ÒVfgƒ��@.Wã¤������G���phpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpY��ÒVfgY��ú¬°¤������(���phpunit/Runner/TestResult/TestResult.phpB?��ÒVfgB?��du±î¤������"���phpunit/Runner/TestSuiteLoader.php���ÒVfg���0ãÙ—¤������"���phpunit/Runner/TestSuiteSorter.php¯%��ÒVfg¯%��¿™?—¤���������phpunit/Runner/Version.phpT��ÒVfgT��JðÍ}¤���������phpunit/TextUI/Application.php*Z��ÒVfg*Z��½i�¥¤������"���phpunit/TextUI/Command/Command.phpD��ÒVfgD��5Ìk¤������9���phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php5��ÒVfg5��R~«­¤������@���phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php2
  3055. ��ÒVfg2
  3056. ��±Dø¤������5���phpunit/TextUI/Command/Commands/ListGroupsCommand.php ��ÒVfg ��1KÜT¤������9���phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php‹��ÒVfg‹��¸!Pï¤������:���phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.phpf ��ÒVfgf ��mø�¤������9���phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php'��ÒVfg'��—^¤������?���phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php��ÒVfg��9>Èž¤������3���phpunit/TextUI/Command/Commands/ShowHelpCommand.phpš��ÒVfgš��¾F@¤������6���phpunit/TextUI/Command/Commands/ShowVersionCommand.php¾��ÒVfg¾��™â'”¤������7���phpunit/TextUI/Command/Commands/VersionCheckCommand.php ��ÒVfg ��¹©0¤������@���phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php"
  3057. ��ÒVfg"
  3058. ��‘‹R¤������!���phpunit/TextUI/Command/Result.phpÌ��ÒVfgÌ��SF¬¤������(���phpunit/TextUI/Configuration/Builder.php³��ÒVfg³��µ^üf¤������,���phpunit/TextUI/Configuration/Cli/Builder.phpQa��ÒVfgQa��ö½Ìš¤������2���phpunit/TextUI/Configuration/Cli/Configuration.phpòÎ��ÒVfgòÎ��Ÿ®Gá¤������.���phpunit/TextUI/Configuration/Cli/Exception.php[��ÒVfg[��¨æÎ'¤������?���phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.phpW��ÒVfgW���&?ؤ������;���phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php¾��ÒVfg¾��º™ò*¤������.���phpunit/TextUI/Configuration/Configuration.phpHš��ÒVfgHš��ú3R^¤������D���phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php’��ÒVfg’��¸«¢O¤������S���phpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php���ÒVfg���©ÙVF¤������N���phpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php‹��ÒVfg‹��6¯Õ¤������4���phpunit/TextUI/Configuration/Exception/Exception.php3��ÒVfg3��¿l´p¤������G���phpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php„��ÒVfg„��´]Ü9¤������H���phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php…��ÒVfg…��N†¤������>���phpunit/TextUI/Configuration/Exception/NoBaselineException.php{��ÒVfg{��%Iû¤������?���phpunit/TextUI/Configuration/Exception/NoBootstrapException.php|��ÒVfg|��eIÂæ¤������D���phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php���ÒVfg���ÍAФ������A���phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php~��ÒVfg~��éDã¤������G���phpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php„��ÒVfg„��¡Þ@À¤������L���phpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php‰��ÒVfg‰��æGt½¤������C���phpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php€��ÒVfg€��¾ÝòΤ������F���phpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.phpƒ��ÒVfgƒ��àÐÿ¤������L���phpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php‰��ÒVfg‰��™jà ¤������'���phpunit/TextUI/Configuration/Merger.php ˆ��ÒVfg ˆ��Ú79¤������+���phpunit/TextUI/Configuration/PhpHandler.phpÀ��ÒVfgÀ��D<¤������)���phpunit/TextUI/Configuration/Registry.php)��ÒVfg)��3¢ØÇ¤������-���phpunit/TextUI/Configuration/SourceFilter.phpõ��ÒVfgõ��ë¥é/¤������-���phpunit/TextUI/Configuration/SourceMapper.php
  3059. ��ÒVfg
  3060. ��ˆ:7¤������1���phpunit/TextUI/Configuration/TestSuiteBuilder.phpD��ÒVfgD��ŸLɤ������/���phpunit/TextUI/Configuration/Value/Constant.php<��ÒVfg<��S:¤������9���phpunit/TextUI/Configuration/Value/ConstantCollection.php™��ÒVfg™��?Tõ.¤������A���phpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php”��ÒVfg”��’J,)¤������0���phpunit/TextUI/Configuration/Value/Directory.php���ÒVfg���x»ª¤������:���phpunit/TextUI/Configuration/Value/DirectoryCollection.php��ÒVfg��°
  3061. †˜¤������B���phpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php¥��ÒVfg¥���c…¤������9���phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php³��ÒVfg³��¾±Pü¤������C���phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php¶��ÒVfg¶��!@Tº¤������K���phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php��ÒVfg��ýÒÕÀ¤������+���phpunit/TextUI/Configuration/Value/File.php.��ÒVfg.��Öçˆã¤������5���phpunit/TextUI/Configuration/Value/FileCollection.php«��ÒVfg«��¨)Ÿ;¤������=���phpunit/TextUI/Configuration/Value/FileCollectionIterator.phph��ÒVfgh��^ù­D¤������6���phpunit/TextUI/Configuration/Value/FilterDirectory.phpƒ��ÒVfgƒ��ÿ=K¤������@���phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php?��ÒVfg?��'’m¤������H���phpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.phpÃ��ÒVfgÃ��ƒÐ4N¤������,���phpunit/TextUI/Configuration/Value/Group.php‹��ÒVfg‹��$»Óë¤������6���phpunit/TextUI/Configuration/Value/GroupCollection.php3��ÒVfg3���úK,¤������>���phpunit/TextUI/Configuration/Value/GroupCollectionIterator.phps��ÒVfgs��øð;¤������1���phpunit/TextUI/Configuration/Value/IniSetting.php/��ÒVfg/��û¬¤������;���phpunit/TextUI/Configuration/Value/IniSettingCollection.php»��ÒVfg»��IïC¤������C���phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.phpª��ÒVfgª��2�-¤������*���phpunit/TextUI/Configuration/Value/Php.phpN��ÒVfgN��}=‰�¤������-���phpunit/TextUI/Configuration/Value/Source.phpv��ÒVfgv��»|c„¤������4���phpunit/TextUI/Configuration/Value/TestDirectory.php���ÒVfg���‰—�L¤������>���phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php(��ÒVfg(��¶mÞJ¤������F���phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php¹��ÒVfg¹��¬8Q¤������/���phpunit/TextUI/Configuration/Value/TestFile.php���ÒVfg���‹É¤������9���phpunit/TextUI/Configuration/Value/TestFileCollection.phpÊ��ÒVfgÊ��½ŽÄd¤������A���phpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php|��ÒVfg|�� ÏN¤������0���phpunit/TextUI/Configuration/Value/TestSuite.php½��ÒVfg½��ó�²Ü¤������:���phpunit/TextUI/Configuration/Value/TestSuiteCollection.phpÿ��ÒVfgÿ��aù‰w¤������B���phpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.phpŸ��ÒVfgŸ��@>¤������/���phpunit/TextUI/Configuration/Value/Variable.phpÃ��ÒVfgÃ��í‘,¤������9���phpunit/TextUI/Configuration/Value/VariableCollection.php™��ÒVfg™��ìTr0¤������A���phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php”��ÒVfg”��l븤������>���phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.phpæ��ÒVfgæ��Ê-¤������?���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php,��ÒVfg,��=?g¸¤������B���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php/��ÒVfg/��ÔŽ)}¤������?���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.phpÚ��ÒVfgÚ��À¢?¤������=���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php^ ��ÒVfg^ ��Ý å¤������<���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php)��ÒVfg)��k�Wµ¤������=���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.phpæ��ÒVfgæ��ñV/¤������<���phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php=��ÒVfg=��:X7³¤������2���phpunit/TextUI/Configuration/Xml/Configuration.phps ��ÒVfgs ��>ß ”¤������9���phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php� ��ÒVfg� ��£§Ï5¤������.���phpunit/TextUI/Configuration/Xml/Exception.php_��ÒVfg_��+øg3¤������.���phpunit/TextUI/Configuration/Xml/Generator.phpß��ÒVfgß��pfL¤������+���phpunit/TextUI/Configuration/Xml/Groups.phpÌ��ÒVfgÌ��aÞl°¤������@���phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.phpü��ÒVfgü��«N(±¤������+���phpunit/TextUI/Configuration/Xml/Loader.php—…��ÒVfg—…��½o6:¤������2���phpunit/TextUI/Configuration/Xml/Logging/Junit.php��ÒVfg��+F¤������4���phpunit/TextUI/Configuration/Xml/Logging/Logging.php$ ��ÒVfg$ ��Ù� ù¤������5���phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php"��ÒVfg"��e{w¤������9���phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php&��ÒVfg&��C_¤������9���phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php&��ÒVfg&��5²¶Ð¤������?���phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.phpö ��ÒVfgö ��,ÌF_¤������A���phpunit/TextUI/Configuration/Xml/Migration/MigrationException.phpv��ÒVfgv��Û[–r¤������I���phpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php��ÒVfg��÷·Ô¤������P���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.phpÂ��ÒVfgÂ��ü¡O¤������P���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php��ÒVfg��[…&Z¤������N���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php��ÒVfg��ŰMZ¤������M���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php°��ÒVfg°��7½ õ¤������N���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php��ÒVfg��*"µ¤������M���phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.phpµ��ÒVfgµ��J¨~*¤������Z���phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.phpÇ��ÒVfgÇ��ÜÀˆ£¤������R���phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.phpL��ÒVfgL��ìÜüà¤������N���phpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.phpô��ÒVfgô��%f»¤������C���phpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php[��ÒVfg[��üfß�¤������e���phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php��ÒVfg��ˆï[¬¤������Z���phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.phpð��ÒVfgð��X.p¤������Y���phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.phpÂ��ÒVfgÂ��’¼ô:¤������Y���phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php- ��ÒVfg- ��( ž~¤������Y���phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php`��ÒVfg`��Tù!@¤������s���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.phpù��ÒVfgù��þÀ-¤������h���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.phpØ��ÒVfgØ��Ÿ. ¤������X���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php¨��ÒVfg¨��«Ðý¤������T���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.phpœ��ÒVfgœ��£ç­5¤������`���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.phpw��ÒVfgw��Õì뚤������f���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.phpô��ÒVfgô��>_T¯¤������m���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php ��ÒVfg ��æSø»¤������K���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.phpå��ÒVfgå���HÒU¤������I���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php’��ÒVfg’��æÍæ¤������H���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.phpÔ��ÒVfgÔ��褤������O���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php’��ÒVfg’��öÕkë¤������V���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php¢��ÒVfg¢��ªF;¿¤������Q���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php
  3062. ��ÒVfg
  3063. ��í¨K;¤������T���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php¡��ÒVfg¡��÷6¢š¤������Y���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php2��ÒVfg2��/¦Ne¤������P���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php���ÒVfg���™©.¤������_���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php���ÒVfg���I������f���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php¹��ÒVfg¹���Ôªw¤������^���phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php���ÒVfg���º_ܤ������N���phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.phpó��ÒVfgó��É·e¹¤������7���phpunit/TextUI/Configuration/Xml/Migration/Migrator.php}��ÒVfg}��ŒF$µ¤������?���phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.phpÐ��ÒVfgÐ��‹~‰¤������,���phpunit/TextUI/Configuration/Xml/PHPUnit.php<>��ÒVfg<>��®û{ؤ������O���phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.phpz��ÒVfgz��‹ õ°¤������I���phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php˜��ÒVfg˜��™{úA¤������B���phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.phpf��ÒVfgf��‘ñôI¤������S���phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php–��ÒVfg–��‘á­&¤������1���phpunit/TextUI/Configuration/Xml/SchemaFinder.phpw��ÒVfgw��—ä
  3064. Z¤������4���phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php$��ÒVfg$��›&�¥¤������?���phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php7��ÒVfg7��ŸF$¤������8���phpunit/TextUI/Configuration/Xml/Validator/Validator.phpœ��ÒVfgœ��·�¢¤������6���phpunit/TextUI/Exception/CannotOpenSocketException.php��ÒVfg��zçá¤������&���phpunit/TextUI/Exception/Exception.php$��ÒVfg$��昤������3���phpunit/TextUI/Exception/InvalidSocketException.php��ÒVfg��ÊI
  3065. ¤������-���phpunit/TextUI/Exception/RuntimeException.phpG��ÒVfgG��¾n V¤������;���phpunit/TextUI/Exception/TestDirectoryNotFoundException.php��ÒVfg��H˲P¤������6���phpunit/TextUI/Exception/TestFileNotFoundException.phpþ��ÒVfgþ��=ƒ|¤���������phpunit/TextUI/Help.php¸7��ÒVfg¸7��ø¼óI¤������A���phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.phpÅ0��ÒVfgÅ0��dÚÙœ¤������c���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php±��ÒVfg±��I„æä¤������G���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php¦��ÒVfg¦��½+å-¤������Z���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.phpk��ÒVfgk�� +b|¤������R���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.phpA��ÒVfgA��è«Î�¤������Q���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php5��ÒVfg5��Û䟤������S���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.phpA��ÒVfgA��»ÝÎˤ������[���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.phpq��ÒVfgq��G ×}¤������S���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.phpA��ÒVfgA��M”[B¤������a���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php���ÒVfg���l¼R ¤������R���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php;��ÒVfg;��‡d¥U¤������_���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php���ÒVfg���Ë Ť������Y���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.phpk��ÒVfgk��»â������Z���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.phpq��ÒVfgq��0\¾¤������b���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php¡��ÒVfg¡��ž"3j¤������]���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.phpƒ��ÒVfgƒ��¡„€ž¤������^���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php‰��ÒVfg‰��4¢zÒ¤������f���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php³��ÒVfg³��¡�+T¤������b���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php›��ÒVfg›��«^NL¤������[���phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.phpw��ÒVfgw��9«‚ï¤������/���phpunit/TextUI/Output/Default/ResultPrinter.php¤I��ÒVfg¤I���1�!¤������9���phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php3��ÒVfg3��ÜÍOg¤������ ���phpunit/TextUI/Output/Facade.phpð ��ÒVfgð ��Œ¶�¥¤������0���phpunit/TextUI/Output/Printer/DefaultPrinter.phpO ��ÒVfgO ��g›¬P¤������-���phpunit/TextUI/Output/Printer/NullPrinter.phpž��ÒVfgž��²¦&‘¤������)���phpunit/TextUI/Output/Printer/Printer.php\��ÒVfg\��gD“ߤ������(���phpunit/TextUI/Output/SummaryPrinter.php
  3066. ��ÒVfg
  3067. ��`[¤������/���phpunit/TextUI/Output/TestDox/ResultPrinter.phpÕ#��ÒVfgÕ#��‡NS¸¤������*���phpunit/TextUI/ShellExitCodeCalculator.php ��ÒVfg ��Lœ§¤���������phpunit/TextUI/TestRunner.php×��ÒVfg×��m/$ؤ������+���phpunit/TextUI/TestSuiteFilterProcessor.phpT��ÒVfgT��n?ÝT¤���������phpunit/Util/Cloner.phpc��ÒVfgc��²Áé¤���������phpunit/Util/Color.php’��ÒVfg’��º|Á…¤������$���phpunit/Util/Exception/Exception.php"��ÒVfg"��ð‘Ò¤������4���phpunit/Util/Exception/InvalidDirectoryException.php��ÒVfg�� ¦ç3¤������/���phpunit/Util/Exception/InvalidJsonException.php\��ÒVfg\��÷nt¤������:���phpunit/Util/Exception/InvalidVersionOperatorException.php��ÒVfg��p2ïÙ¤������.���phpunit/Util/Exception/PhpProcessException.phpm��ÒVfgm��Zž|¤������'���phpunit/Util/Exception/XmlException.phpf��ÒVfgf��Î;´Q¤���������phpunit/Util/ExcludeList.phpÅ��ÒVfgÅ��b+"²¤���������phpunit/Util/Exporter.phpI��ÒVfgI�� Æô¶¤���������phpunit/Util/Filesystem.phpO��ÒVfgO��Ć|¤���������phpunit/Util/Filter.phpV ��ÒVfgV ��À,w|¤���������phpunit/Util/GlobalState.php¡��ÒVfg¡��©³¤������ ���phpunit/Util/Http/Downloader.phpp��ÒVfgp�� ˜žu¤������#���phpunit/Util/Http/PhpDownloader.php ��ÒVfg ��KÃ>Ƥ���������phpunit/Util/Json.phpC ��ÒVfgC ��Åf ¤������'���phpunit/Util/PHP/AbstractPhpProcess.php±��ÒVfg±��ûÚ5S¤������&���phpunit/Util/PHP/DefaultPhpProcess.php‘ ��ÒVfg‘ ��#=¤������+���phpunit/Util/PHP/Template/TestCaseClass.tpld ��ÒVfgd ��f{u ¤������,���phpunit/Util/PHP/Template/TestCaseMethod.tplj ��ÒVfgj ��ÎIñ®¤������*���phpunit/Util/PHP/Template/PhptTestCase.tplÓ��ÒVfgÓ��>Üßu¤���������phpunit/Util/Reflection.phpS ��ÒVfgS ��;�ؤ���������phpunit/Util/Test.phpò��ÒVfgò��N Òì¤������(���phpunit/Util/ThrowableToStringMapper.php£��ÒVfg£��†�¤������*���phpunit/Util/VersionComparisonOperator.php1��ÒVfg1�� Ìšð¤���������phpunit/Util/Xml/Loader.phpÚ ��ÒVfgÚ ��W&Èͤ���������phpunit/Util/Xml/Xml.php*��ÒVfg*��u?Qf¤���������sbom.xml�$��ÒVfg�$��Eñ$V¤���������schema/10.0.xsd=��ÒVfg=��|H¤���������schema/10.1.xsd«B��ÒVfg«B��Ü­r—¤���������schema/10.2.xsdQE��ÒVfgQE��¸çÿn¤���������schema/10.3.xsdF��ÒVfgF��›¶3&¤���������schema/10.4.xsdGF��ÒVfgGF��?”ñÁ¤���������schema/8.5.xsdÓB��ÒVfgÓB��2A[­¤���������schema/9.0.xsd4B��ÒVfg4B��•¨7w¤���������schema/9.1.xsdÕB��ÒVfgÕB��ßq'8¤���������schema/9.2.xsdÜB��ÒVfgÜB��c·Á-¤���������schema/9.3.xsd¼E��ÒVfg¼E��¿ùq¤���������schema/9.4.xsd
  3068. F��ÒVfg
  3069. F��DOFI¤���������schema/9.5.xsdDF��ÒVfgDF��ûùs|¤���������sebastian-cli-parser/LICENSEû��ÒVfgû��§Øk¤���������sebastian-cli-parser/Parser.php¹��ÒVfg¹��®B%ç¤������<���sebastian-cli-parser/exceptions/AmbiguousOptionException.phpJ��ÒVfgJ��kK*¤������-���sebastian-cli-parser/exceptions/Exception.phpy��ÒVfgy��>€±¤������G���sebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.phpc��ÒVfgc��ŠRjY¤������J���sebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.phpl��ÒVfgl��zQ¢¤������:���sebastian-cli-parser/exceptions/UnknownOptionException.phpC��ÒVfgC��€*tP¤������*���sebastian-code-unit-reverse-lookup/LICENSEû��ÒVfgû��f‰œ¤������-���sebastian-code-unit-reverse-lookup/Wizard.php¦ ��ÒVfg¦ ��îÝC÷¤������'���sebastian-code-unit/ClassMethodUnit.php��ÒVfg��“v¤������!���sebastian-code-unit/ClassUnit.php��ÒVfg��ÖJk¤������ ���sebastian-code-unit/CodeUnit.php(��ÒVfg(��§Hפ������*���sebastian-code-unit/CodeUnitCollection.phpß��ÒVfgß��ñ�j¤������2���sebastian-code-unit/CodeUnitCollectionIterator.php\��ÒVfg\��×äÙѤ������ ���sebastian-code-unit/FileUnit.php��ÒVfg��owÿ]¤������$���sebastian-code-unit/FunctionUnit.php��ÒVfg��Òô‹•¤������+���sebastian-code-unit/InterfaceMethodUnit.php"��ÒVfg"��_!_¤������%���sebastian-code-unit/InterfaceUnit.php��ÒVfg��š%¤���������sebastian-code-unit/LICENSEû��ÒVfgû��´P@Ù¤���������sebastian-code-unit/Mapper.php��ÒVfg��"ªh8¤������'���sebastian-code-unit/TraitMethodUnit.php��ÒVfg��%E¾:¤������!���sebastian-code-unit/TraitUnit.php��ÒVfg��ß•¤������,���sebastian-code-unit/exceptions/Exception.phpw��ÒVfgw��ž5ŒÇ¤������;���sebastian-code-unit/exceptions/InvalidCodeUnitException.php«��ÒVfg«��MvÔŠ¤������3���sebastian-code-unit/exceptions/NoTraitException.php£��ÒVfg£��å]Ü5¤������6���sebastian-code-unit/exceptions/ReflectionException.php¦��ÒVfg¦��cÈQí¤������(���sebastian-comparator/ArrayComparator.php ��ÒVfg ��œ-_o¤������#���sebastian-comparator/Comparator.phpR��ÒVfgR���¨À?¤������*���sebastian-comparator/ComparisonFailure.php ��ÒVfg ��*ý*¤������*���sebastian-comparator/DOMNodeComparator.phpé��ÒVfgé��6Ÿ?û¤������+���sebastian-comparator/DateTimeComparator.phpY��ÒVfgY��†6\¤������,���sebastian-comparator/ExceptionComparator.php“��ÒVfg“��K\ ¤������ ���sebastian-comparator/Factory.phpz ��ÒVfgz ��¢|=|¤���������sebastian-comparator/LICENSEû��ÒVfgû��ƒÜ¡7¤������-���sebastian-comparator/MockObjectComparator.php@��ÒVfg@��ASF ¤������*���sebastian-comparator/NumericComparator.php��ÒVfg��ÌŒ†¤������)���sebastian-comparator/ObjectComparator.php
  3070. ��ÒVfg
  3071. ��2ÿ }¤������+���sebastian-comparator/ResourceComparator.phpO��ÒVfgO��dnŒ¤������)���sebastian-comparator/ScalarComparator.phpÙ ��ÒVfgÙ ��©îc„¤������3���sebastian-comparator/SplObjectStorageComparator.php ��ÒVfg ��×bf¤������'���sebastian-comparator/TypeComparator.php…��ÒVfg…��U
  3072. h‰¤������-���sebastian-comparator/exceptions/Exception.phpz��ÒVfgz��¶£Ï¤������4���sebastian-comparator/exceptions/RuntimeException.php‘��ÒVfg‘��€èõ_¤������#���sebastian-complexity/Calculator.phpþ��ÒVfgþ��ߎó*¤������.���sebastian-complexity/Complexity/Complexity.php2��ÒVfg2��jùÞ;¤������8���sebastian-complexity/Complexity/ComplexityCollection.php
  3073. ��ÒVfg
  3074. ��·ˆu¤������@���sebastian-complexity/Complexity/ComplexityCollectionIterator.php��ÒVfg��œy€¤������,���sebastian-complexity/Exception/Exception.phpz��ÒVfgz��Ȭ�ˤ������3���sebastian-complexity/Exception/RuntimeException.php‘��ÒVfg‘��¼Ìé¤���������sebastian-complexity/LICENSEû��ÒVfgû��´P@Ù¤������=���sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php��ÒVfg��9q2ޤ������G���sebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php8��ÒVfg8��É®¤���������sebastian-diff/Chunk.php¤ ��ÒVfg¤ �� “™¤���������sebastian-diff/Diff.phpS��ÒVfgS��•:�Á¤���������sebastian-diff/Differ.phpù��ÒVfgù��ìˆöJ¤������3���sebastian-diff/Exception/ConfigurationException.php&��ÒVfg&��]?…‹¤������&���sebastian-diff/Exception/Exception.phpn��ÒVfgn��šÀ/\¤������5���sebastian-diff/Exception/InvalidArgumentException.php���ÒVfg���æ$y¤���������sebastian-diff/LICENSEû��ÒVfgû��ƒÜ¡7¤���������sebastian-diff/Line.php��ÒVfg��ƒ¯FJ¤������5���sebastian-diff/LongestCommonSubsequenceCalculator.phpô��ÒVfgô��ep€6¤������D���sebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.phpü��ÒVfgü��æeE¤������4���sebastian-diff/Output/AbstractChunkOutputBuilder.phpù��ÒVfgù��?&ðæ¤������/���sebastian-diff/Output/DiffOnlyOutputBuilder.php€��ÒVfg€��Ù| ¨¤������4���sebastian-diff/Output/DiffOutputBuilderInterface.php��ÒVfg��pmö¤������8���sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php_(��ÒVfg_(��~I;¤������2���sebastian-diff/Output/UnifiedDiffOutputBuilder.phpÕ��ÒVfgÕ��Y6‰þ¤���������sebastian-diff/Parser.phpÚ ��ÒVfgÚ ��&pѤ������B���sebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.phpù��ÒVfgù��Nœh ¤������!���sebastian-environment/Console.php¹��ÒVfg¹��*öE2¤���������sebastian-environment/LICENSEû��ÒVfgû��'|¯¤������!���sebastian-environment/Runtime.php‡��ÒVfg‡��R»µ¤���������sebastian-exporter/Exporter.php‰"��ÒVfg‰"��ÔWg¤���������sebastian-exporter/LICENSEû��ÒVfgû��ƒÜ¡7¤������'���sebastian-global-state/CodeExporter.phpg ��ÒVfgg �� “²V¤������&���sebastian-global-state/ExcludeList.php
  3075. ��ÒVfg
  3076. �� ¥î¤���������sebastian-global-state/LICENSEû��ÒVfgû��ßik¤������#���sebastian-global-state/Restorer.php3 ��ÒVfg3 ��¼†¤������#���sebastian-global-state/Snapshot.phpî&��ÒVfgî&��æN‘¤������/���sebastian-global-state/exceptions/Exception.php}��ÒVfg}��¶µâ´¤������6���sebastian-global-state/exceptions/RuntimeException.php”��ÒVfg”��#Ú™¤������#���sebastian-lines-of-code/Counter.phpÌ��ÒVfgÌ�� Z�~¤������/���sebastian-lines-of-code/Exception/Exception.php~��ÒVfg~��%>²ú¤������>���sebastian-lines-of-code/Exception/IllogicalValuesException.php®��ÒVfg®��Êårÿ¤������<���sebastian-lines-of-code/Exception/NegativeValueException.phpÀ��ÒVfgÀ��Ë&«Ó¤������6���sebastian-lines-of-code/Exception/RuntimeException.php•��ÒVfg•��Ñ)Ϲ¤���������sebastian-lines-of-code/LICENSEû��ÒVfgû��´P@Ù¤������/���sebastian-lines-of-code/LineCountingVisitor.php ��ÒVfg ��S¼�ö¤������'���sebastian-lines-of-code/LinesOfCode.php ��ÒVfg ��¼„À”¤������*���sebastian-object-enumerator/Enumerator.phpà��ÒVfgà��×=¯¤������.���sebastian-object-reflector/ObjectReflector.php���ÒVfg���Ý9Oî¤������'���sebastian-recursion-context/Context.php��ÒVfg���†M¤������#���sebastian-recursion-context/LICENSEû��ÒVfgû���TŠò¤���������sebastian-type/LICENSEû��ÒVfgû�� ïù÷¤���������sebastian-type/Parameter.php��ÒVfg��¨øEœ¤������#���sebastian-type/ReflectionMapper.phpÄ��ÒVfgÄ��¦l ܤ���������sebastian-type/TypeName.php���ÒVfg���íA­Ö¤������&���sebastian-type/exception/Exception.phpn��ÒVfgn��ÑH3ç¤������-���sebastian-type/exception/RuntimeException.php…��ÒVfg…��¶;sÖ¤������$���sebastian-type/type/CallableType.phpÎ��ÒVfgÎ��¾M{)¤������!���sebastian-type/type/FalseType.phpb��ÒVfgb��nÞ…^¤������)���sebastian-type/type/GenericObjectType.php ��ÒVfg ��ËIG¶¤������(���sebastian-type/type/IntersectionType.php¥
  3077. ��ÒVfg¥
  3078. ��°sؤ������$���sebastian-type/type/IterableType.phpé��ÒVfgé��Ð~ü¤������!���sebastian-type/type/MixedType.php&��ÒVfg&��ÔöºÔ¤������!���sebastian-type/type/NeverType.php×��ÒVfg×��³Ž×S¤������ ���sebastian-type/type/NullType.php!��ÒVfg!��ný6ޤ������"���sebastian-type/type/ObjectType.php$��ÒVfg$��Ýaõ`¤������"���sebastian-type/type/SimpleType.php*��ÒVfg*��'òhH¤������"���sebastian-type/type/StaticType.phpÂ��ÒVfgÂ��s92¤������ ���sebastian-type/type/TrueType.php]��ÒVfg]��¬z¬¤���������sebastian-type/type/Type.phpŒ��ÒVfgŒ��ɤ������!���sebastian-type/type/UnionType.php% ��ÒVfg% ��ÕE¤������#���sebastian-type/type/UnknownType.php��ÒVfg��H´”¤������ ���sebastian-type/type/VoidType.phpÓ��ÒVfgÓ��¾[Þÿ¤���������sebastian-version/LICENSEû��ÒVfgû��‚Voç¤���������sebastian-version/Version.php–��ÒVfg–��¼Døç¤���������theseer-tokenizer/Exception.phpr���ÒVfgr���ÊÂmœ¤���������theseer-tokenizer/LICENSEü��ÒVfgü��ïR (¤������"���theseer-tokenizer/NamespaceUri.phpJ��ÒVfgJ��Wç]¤������+���theseer-tokenizer/NamespaceUriException.php}���ÒVfg}���aÕ“�¤���������theseer-tokenizer/Token.php—��ÒVfg—��K•`¤������%���theseer-tokenizer/TokenCollection.php��ÒVfg��N´}¤������.���theseer-tokenizer/TokenCollectionException.php€���ÒVfg€���5�ɤ���������theseer-tokenizer/Tokenizer.php ��ÒVfg ��!ŠøN¤������#���theseer-tokenizer/XMLSerializer.phpê��ÒVfgê��u(Õ¤������{
  3079. "_readme": [
  3080. "This file locks the dependencies of your project to a known state",
  3081. "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
  3082. "This file is @generated automatically"
  3083. ],
  3084. "content-hash": "1d92bc903b3b4a03ad2d073e61c577ee",
  3085. "packages": [
  3086. {
  3087. "name": "myclabs/deep-copy",
  3088. "version": "1.12.1",
  3089. "source": {
  3090. "type": "git",
  3091. "url": "https://github.com/myclabs/DeepCopy.git",
  3092. "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
  3093. },
  3094. "dist": {
  3095. "type": "zip",
  3096. "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
  3097. "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
  3098. "shasum": ""
  3099. },
  3100. "require": {
  3101. "php": "^7.1 || ^8.0"
  3102. },
  3103. "conflict": {
  3104. "doctrine/collections": "<1.6.8",
  3105. "doctrine/common": "<2.13.3 || >=3 <3.2.2"
  3106. },
  3107. "require-dev": {
  3108. "doctrine/collections": "^1.6.8",
  3109. "doctrine/common": "^2.13.3 || ^3.2.2",
  3110. "phpspec/prophecy": "^1.10",
  3111. "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
  3112. },
  3113. "type": "library",
  3114. "autoload": {
  3115. "files": [
  3116. "src/DeepCopy/deep_copy.php"
  3117. ],
  3118. "psr-4": {
  3119. "DeepCopy\\": "src/DeepCopy/"
  3120. }
  3121. },
  3122. "notification-url": "https://packagist.org/downloads/",
  3123. "license": [
  3124. "MIT"
  3125. ],
  3126. "description": "Create deep copies (clones) of your objects",
  3127. "keywords": [
  3128. "clone",
  3129. "copy",
  3130. "duplicate",
  3131. "object",
  3132. "object graph"
  3133. ],
  3134. "support": {
  3135. "issues": "https://github.com/myclabs/DeepCopy/issues",
  3136. "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
  3137. },
  3138. "funding": [
  3139. {
  3140. "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
  3141. "type": "tidelift"
  3142. }
  3143. ],
  3144. "time": "2024-11-08T17:47:46+00:00"
  3145. },
  3146. {
  3147. "name": "nikic/php-parser",
  3148. "version": "v5.3.1",
  3149. "source": {
  3150. "type": "git",
  3151. "url": "https://github.com/nikic/PHP-Parser.git",
  3152. "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
  3153. },
  3154. "dist": {
  3155. "type": "zip",
  3156. "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
  3157. "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
  3158. "shasum": ""
  3159. },
  3160. "require": {
  3161. "ext-ctype": "*",
  3162. "ext-json": "*",
  3163. "ext-tokenizer": "*",
  3164. "php": ">=7.4"
  3165. },
  3166. "require-dev": {
  3167. "ircmaxell/php-yacc": "^0.0.7",
  3168. "phpunit/phpunit": "^9.0"
  3169. },
  3170. "bin": [
  3171. "bin/php-parse"
  3172. ],
  3173. "type": "library",
  3174. "extra": {
  3175. "branch-alias": {
  3176. "dev-master": "5.0-dev"
  3177. }
  3178. },
  3179. "autoload": {
  3180. "psr-4": {
  3181. "PhpParser\\": "lib/PhpParser"
  3182. }
  3183. },
  3184. "notification-url": "https://packagist.org/downloads/",
  3185. "license": [
  3186. "BSD-3-Clause"
  3187. ],
  3188. "authors": [
  3189. {
  3190. "name": "Nikita Popov"
  3191. }
  3192. ],
  3193. "description": "A PHP parser written in PHP",
  3194. "keywords": [
  3195. "parser",
  3196. "php"
  3197. ],
  3198. "support": {
  3199. "issues": "https://github.com/nikic/PHP-Parser/issues",
  3200. "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1"
  3201. },
  3202. "time": "2024-10-08T18:51:32+00:00"
  3203. },
  3204. {
  3205. "name": "phar-io/manifest",
  3206. "version": "2.0.4",
  3207. "source": {
  3208. "type": "git",
  3209. "url": "https://github.com/phar-io/manifest.git",
  3210. "reference": "54750ef60c58e43759730615a392c31c80e23176"
  3211. },
  3212. "dist": {
  3213. "type": "zip",
  3214. "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
  3215. "reference": "54750ef60c58e43759730615a392c31c80e23176",
  3216. "shasum": ""
  3217. },
  3218. "require": {
  3219. "ext-dom": "*",
  3220. "ext-libxml": "*",
  3221. "ext-phar": "*",
  3222. "ext-xmlwriter": "*",
  3223. "phar-io/version": "^3.0.1",
  3224. "php": "^7.2 || ^8.0"
  3225. },
  3226. "type": "library",
  3227. "extra": {
  3228. "branch-alias": {
  3229. "dev-master": "2.0.x-dev"
  3230. }
  3231. },
  3232. "autoload": {
  3233. "classmap": [
  3234. "src/"
  3235. ]
  3236. },
  3237. "notification-url": "https://packagist.org/downloads/",
  3238. "license": [
  3239. "BSD-3-Clause"
  3240. ],
  3241. "authors": [
  3242. {
  3243. "name": "Arne Blankerts",
  3244. "email": "arne@blankerts.de",
  3245. "role": "Developer"
  3246. },
  3247. {
  3248. "name": "Sebastian Heuer",
  3249. "email": "sebastian@phpeople.de",
  3250. "role": "Developer"
  3251. },
  3252. {
  3253. "name": "Sebastian Bergmann",
  3254. "email": "sebastian@phpunit.de",
  3255. "role": "Developer"
  3256. }
  3257. ],
  3258. "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
  3259. "support": {
  3260. "issues": "https://github.com/phar-io/manifest/issues",
  3261. "source": "https://github.com/phar-io/manifest/tree/2.0.4"
  3262. },
  3263. "funding": [
  3264. {
  3265. "url": "https://github.com/theseer",
  3266. "type": "github"
  3267. }
  3268. ],
  3269. "time": "2024-03-03T12:33:53+00:00"
  3270. },
  3271. {
  3272. "name": "phar-io/version",
  3273. "version": "3.2.1",
  3274. "source": {
  3275. "type": "git",
  3276. "url": "https://github.com/phar-io/version.git",
  3277. "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
  3278. },
  3279. "dist": {
  3280. "type": "zip",
  3281. "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
  3282. "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
  3283. "shasum": ""
  3284. },
  3285. "require": {
  3286. "php": "^7.2 || ^8.0"
  3287. },
  3288. "type": "library",
  3289. "autoload": {
  3290. "classmap": [
  3291. "src/"
  3292. ]
  3293. },
  3294. "notification-url": "https://packagist.org/downloads/",
  3295. "license": [
  3296. "BSD-3-Clause"
  3297. ],
  3298. "authors": [
  3299. {
  3300. "name": "Arne Blankerts",
  3301. "email": "arne@blankerts.de",
  3302. "role": "Developer"
  3303. },
  3304. {
  3305. "name": "Sebastian Heuer",
  3306. "email": "sebastian@phpeople.de",
  3307. "role": "Developer"
  3308. },
  3309. {
  3310. "name": "Sebastian Bergmann",
  3311. "email": "sebastian@phpunit.de",
  3312. "role": "Developer"
  3313. }
  3314. ],
  3315. "description": "Library for handling version information and constraints",
  3316. "support": {
  3317. "issues": "https://github.com/phar-io/version/issues",
  3318. "source": "https://github.com/phar-io/version/tree/3.2.1"
  3319. },
  3320. "time": "2022-02-21T01:04:05+00:00"
  3321. },
  3322. {
  3323. "name": "phpunit/php-code-coverage",
  3324. "version": "10.1.16",
  3325. "source": {
  3326. "type": "git",
  3327. "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
  3328. "reference": "7e308268858ed6baedc8704a304727d20bc07c77"
  3329. },
  3330. "dist": {
  3331. "type": "zip",
  3332. "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77",
  3333. "reference": "7e308268858ed6baedc8704a304727d20bc07c77",
  3334. "shasum": ""
  3335. },
  3336. "require": {
  3337. "ext-dom": "*",
  3338. "ext-libxml": "*",
  3339. "ext-xmlwriter": "*",
  3340. "nikic/php-parser": "^4.19.1 || ^5.1.0",
  3341. "php": ">=8.1",
  3342. "phpunit/php-file-iterator": "^4.1.0",
  3343. "phpunit/php-text-template": "^3.0.1",
  3344. "sebastian/code-unit-reverse-lookup": "^3.0.0",
  3345. "sebastian/complexity": "^3.2.0",
  3346. "sebastian/environment": "^6.1.0",
  3347. "sebastian/lines-of-code": "^2.0.2",
  3348. "sebastian/version": "^4.0.1",
  3349. "theseer/tokenizer": "^1.2.3"
  3350. },
  3351. "require-dev": {
  3352. "phpunit/phpunit": "^10.1"
  3353. },
  3354. "suggest": {
  3355. "ext-pcov": "PHP extension that provides line coverage",
  3356. "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
  3357. },
  3358. "type": "library",
  3359. "extra": {
  3360. "branch-alias": {
  3361. "dev-main": "10.1.x-dev"
  3362. }
  3363. },
  3364. "autoload": {
  3365. "classmap": [
  3366. "src/"
  3367. ]
  3368. },
  3369. "notification-url": "https://packagist.org/downloads/",
  3370. "license": [
  3371. "BSD-3-Clause"
  3372. ],
  3373. "authors": [
  3374. {
  3375. "name": "Sebastian Bergmann",
  3376. "email": "sebastian@phpunit.de",
  3377. "role": "lead"
  3378. }
  3379. ],
  3380. "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
  3381. "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
  3382. "keywords": [
  3383. "coverage",
  3384. "testing",
  3385. "xunit"
  3386. ],
  3387. "support": {
  3388. "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
  3389. "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
  3390. "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16"
  3391. },
  3392. "funding": [
  3393. {
  3394. "url": "https://github.com/sebastianbergmann",
  3395. "type": "github"
  3396. }
  3397. ],
  3398. "time": "2024-08-22T04:31:57+00:00"
  3399. },
  3400. {
  3401. "name": "phpunit/php-file-iterator",
  3402. "version": "4.1.0",
  3403. "source": {
  3404. "type": "git",
  3405. "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
  3406. "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c"
  3407. },
  3408. "dist": {
  3409. "type": "zip",
  3410. "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c",
  3411. "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c",
  3412. "shasum": ""
  3413. },
  3414. "require": {
  3415. "php": ">=8.1"
  3416. },
  3417. "require-dev": {
  3418. "phpunit/phpunit": "^10.0"
  3419. },
  3420. "type": "library",
  3421. "extra": {
  3422. "branch-alias": {
  3423. "dev-main": "4.0-dev"
  3424. }
  3425. },
  3426. "autoload": {
  3427. "classmap": [
  3428. "src/"
  3429. ]
  3430. },
  3431. "notification-url": "https://packagist.org/downloads/",
  3432. "license": [
  3433. "BSD-3-Clause"
  3434. ],
  3435. "authors": [
  3436. {
  3437. "name": "Sebastian Bergmann",
  3438. "email": "sebastian@phpunit.de",
  3439. "role": "lead"
  3440. }
  3441. ],
  3442. "description": "FilterIterator implementation that filters files based on a list of suffixes.",
  3443. "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
  3444. "keywords": [
  3445. "filesystem",
  3446. "iterator"
  3447. ],
  3448. "support": {
  3449. "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
  3450. "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
  3451. "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0"
  3452. },
  3453. "funding": [
  3454. {
  3455. "url": "https://github.com/sebastianbergmann",
  3456. "type": "github"
  3457. }
  3458. ],
  3459. "time": "2023-08-31T06:24:48+00:00"
  3460. },
  3461. {
  3462. "name": "phpunit/php-invoker",
  3463. "version": "4.0.0",
  3464. "source": {
  3465. "type": "git",
  3466. "url": "https://github.com/sebastianbergmann/php-invoker.git",
  3467. "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7"
  3468. },
  3469. "dist": {
  3470. "type": "zip",
  3471. "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
  3472. "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
  3473. "shasum": ""
  3474. },
  3475. "require": {
  3476. "php": ">=8.1"
  3477. },
  3478. "require-dev": {
  3479. "ext-pcntl": "*",
  3480. "phpunit/phpunit": "^10.0"
  3481. },
  3482. "suggest": {
  3483. "ext-pcntl": "*"
  3484. },
  3485. "type": "library",
  3486. "extra": {
  3487. "branch-alias": {
  3488. "dev-main": "4.0-dev"
  3489. }
  3490. },
  3491. "autoload": {
  3492. "classmap": [
  3493. "src/"
  3494. ]
  3495. },
  3496. "notification-url": "https://packagist.org/downloads/",
  3497. "license": [
  3498. "BSD-3-Clause"
  3499. ],
  3500. "authors": [
  3501. {
  3502. "name": "Sebastian Bergmann",
  3503. "email": "sebastian@phpunit.de",
  3504. "role": "lead"
  3505. }
  3506. ],
  3507. "description": "Invoke callables with a timeout",
  3508. "homepage": "https://github.com/sebastianbergmann/php-invoker/",
  3509. "keywords": [
  3510. "process"
  3511. ],
  3512. "support": {
  3513. "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
  3514. "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0"
  3515. },
  3516. "funding": [
  3517. {
  3518. "url": "https://github.com/sebastianbergmann",
  3519. "type": "github"
  3520. }
  3521. ],
  3522. "time": "2023-02-03T06:56:09+00:00"
  3523. },
  3524. {
  3525. "name": "phpunit/php-text-template",
  3526. "version": "3.0.1",
  3527. "source": {
  3528. "type": "git",
  3529. "url": "https://github.com/sebastianbergmann/php-text-template.git",
  3530. "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748"
  3531. },
  3532. "dist": {
  3533. "type": "zip",
  3534. "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748",
  3535. "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748",
  3536. "shasum": ""
  3537. },
  3538. "require": {
  3539. "php": ">=8.1"
  3540. },
  3541. "require-dev": {
  3542. "phpunit/phpunit": "^10.0"
  3543. },
  3544. "type": "library",
  3545. "extra": {
  3546. "branch-alias": {
  3547. "dev-main": "3.0-dev"
  3548. }
  3549. },
  3550. "autoload": {
  3551. "classmap": [
  3552. "src/"
  3553. ]
  3554. },
  3555. "notification-url": "https://packagist.org/downloads/",
  3556. "license": [
  3557. "BSD-3-Clause"
  3558. ],
  3559. "authors": [
  3560. {
  3561. "name": "Sebastian Bergmann",
  3562. "email": "sebastian@phpunit.de",
  3563. "role": "lead"
  3564. }
  3565. ],
  3566. "description": "Simple template engine.",
  3567. "homepage": "https://github.com/sebastianbergmann/php-text-template/",
  3568. "keywords": [
  3569. "template"
  3570. ],
  3571. "support": {
  3572. "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
  3573. "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
  3574. "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1"
  3575. },
  3576. "funding": [
  3577. {
  3578. "url": "https://github.com/sebastianbergmann",
  3579. "type": "github"
  3580. }
  3581. ],
  3582. "time": "2023-08-31T14:07:24+00:00"
  3583. },
  3584. {
  3585. "name": "phpunit/php-timer",
  3586. "version": "6.0.0",
  3587. "source": {
  3588. "type": "git",
  3589. "url": "https://github.com/sebastianbergmann/php-timer.git",
  3590. "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d"
  3591. },
  3592. "dist": {
  3593. "type": "zip",
  3594. "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d",
  3595. "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d",
  3596. "shasum": ""
  3597. },
  3598. "require": {
  3599. "php": ">=8.1"
  3600. },
  3601. "require-dev": {
  3602. "phpunit/phpunit": "^10.0"
  3603. },
  3604. "type": "library",
  3605. "extra": {
  3606. "branch-alias": {
  3607. "dev-main": "6.0-dev"
  3608. }
  3609. },
  3610. "autoload": {
  3611. "classmap": [
  3612. "src/"
  3613. ]
  3614. },
  3615. "notification-url": "https://packagist.org/downloads/",
  3616. "license": [
  3617. "BSD-3-Clause"
  3618. ],
  3619. "authors": [
  3620. {
  3621. "name": "Sebastian Bergmann",
  3622. "email": "sebastian@phpunit.de",
  3623. "role": "lead"
  3624. }
  3625. ],
  3626. "description": "Utility class for timing",
  3627. "homepage": "https://github.com/sebastianbergmann/php-timer/",
  3628. "keywords": [
  3629. "timer"
  3630. ],
  3631. "support": {
  3632. "issues": "https://github.com/sebastianbergmann/php-timer/issues",
  3633. "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0"
  3634. },
  3635. "funding": [
  3636. {
  3637. "url": "https://github.com/sebastianbergmann",
  3638. "type": "github"
  3639. }
  3640. ],
  3641. "time": "2023-02-03T06:57:52+00:00"
  3642. },
  3643. {
  3644. "name": "sebastian/cli-parser",
  3645. "version": "2.0.1",
  3646. "source": {
  3647. "type": "git",
  3648. "url": "https://github.com/sebastianbergmann/cli-parser.git",
  3649. "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084"
  3650. },
  3651. "dist": {
  3652. "type": "zip",
  3653. "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084",
  3654. "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084",
  3655. "shasum": ""
  3656. },
  3657. "require": {
  3658. "php": ">=8.1"
  3659. },
  3660. "require-dev": {
  3661. "phpunit/phpunit": "^10.0"
  3662. },
  3663. "type": "library",
  3664. "extra": {
  3665. "branch-alias": {
  3666. "dev-main": "2.0-dev"
  3667. }
  3668. },
  3669. "autoload": {
  3670. "classmap": [
  3671. "src/"
  3672. ]
  3673. },
  3674. "notification-url": "https://packagist.org/downloads/",
  3675. "license": [
  3676. "BSD-3-Clause"
  3677. ],
  3678. "authors": [
  3679. {
  3680. "name": "Sebastian Bergmann",
  3681. "email": "sebastian@phpunit.de",
  3682. "role": "lead"
  3683. }
  3684. ],
  3685. "description": "Library for parsing CLI options",
  3686. "homepage": "https://github.com/sebastianbergmann/cli-parser",
  3687. "support": {
  3688. "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
  3689. "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
  3690. "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1"
  3691. },
  3692. "funding": [
  3693. {
  3694. "url": "https://github.com/sebastianbergmann",
  3695. "type": "github"
  3696. }
  3697. ],
  3698. "time": "2024-03-02T07:12:49+00:00"
  3699. },
  3700. {
  3701. "name": "sebastian/code-unit",
  3702. "version": "2.0.0",
  3703. "source": {
  3704. "type": "git",
  3705. "url": "https://github.com/sebastianbergmann/code-unit.git",
  3706. "reference": "a81fee9eef0b7a76af11d121767abc44c104e503"
  3707. },
  3708. "dist": {
  3709. "type": "zip",
  3710. "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503",
  3711. "reference": "a81fee9eef0b7a76af11d121767abc44c104e503",
  3712. "shasum": ""
  3713. },
  3714. "require": {
  3715. "php": ">=8.1"
  3716. },
  3717. "require-dev": {
  3718. "phpunit/phpunit": "^10.0"
  3719. },
  3720. "type": "library",
  3721. "extra": {
  3722. "branch-alias": {
  3723. "dev-main": "2.0-dev"
  3724. }
  3725. },
  3726. "autoload": {
  3727. "classmap": [
  3728. "src/"
  3729. ]
  3730. },
  3731. "notification-url": "https://packagist.org/downloads/",
  3732. "license": [
  3733. "BSD-3-Clause"
  3734. ],
  3735. "authors": [
  3736. {
  3737. "name": "Sebastian Bergmann",
  3738. "email": "sebastian@phpunit.de",
  3739. "role": "lead"
  3740. }
  3741. ],
  3742. "description": "Collection of value objects that represent the PHP code units",
  3743. "homepage": "https://github.com/sebastianbergmann/code-unit",
  3744. "support": {
  3745. "issues": "https://github.com/sebastianbergmann/code-unit/issues",
  3746. "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0"
  3747. },
  3748. "funding": [
  3749. {
  3750. "url": "https://github.com/sebastianbergmann",
  3751. "type": "github"
  3752. }
  3753. ],
  3754. "time": "2023-02-03T06:58:43+00:00"
  3755. },
  3756. {
  3757. "name": "sebastian/code-unit-reverse-lookup",
  3758. "version": "3.0.0",
  3759. "source": {
  3760. "type": "git",
  3761. "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
  3762. "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d"
  3763. },
  3764. "dist": {
  3765. "type": "zip",
  3766. "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
  3767. "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
  3768. "shasum": ""
  3769. },
  3770. "require": {
  3771. "php": ">=8.1"
  3772. },
  3773. "require-dev": {
  3774. "phpunit/phpunit": "^10.0"
  3775. },
  3776. "type": "library",
  3777. "extra": {
  3778. "branch-alias": {
  3779. "dev-main": "3.0-dev"
  3780. }
  3781. },
  3782. "autoload": {
  3783. "classmap": [
  3784. "src/"
  3785. ]
  3786. },
  3787. "notification-url": "https://packagist.org/downloads/",
  3788. "license": [
  3789. "BSD-3-Clause"
  3790. ],
  3791. "authors": [
  3792. {
  3793. "name": "Sebastian Bergmann",
  3794. "email": "sebastian@phpunit.de"
  3795. }
  3796. ],
  3797. "description": "Looks up which function or method a line of code belongs to",
  3798. "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
  3799. "support": {
  3800. "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
  3801. "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0"
  3802. },
  3803. "funding": [
  3804. {
  3805. "url": "https://github.com/sebastianbergmann",
  3806. "type": "github"
  3807. }
  3808. ],
  3809. "time": "2023-02-03T06:59:15+00:00"
  3810. },
  3811. {
  3812. "name": "sebastian/comparator",
  3813. "version": "5.0.3",
  3814. "source": {
  3815. "type": "git",
  3816. "url": "https://github.com/sebastianbergmann/comparator.git",
  3817. "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e"
  3818. },
  3819. "dist": {
  3820. "type": "zip",
  3821. "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e",
  3822. "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e",
  3823. "shasum": ""
  3824. },
  3825. "require": {
  3826. "ext-dom": "*",
  3827. "ext-mbstring": "*",
  3828. "php": ">=8.1",
  3829. "sebastian/diff": "^5.0",
  3830. "sebastian/exporter": "^5.0"
  3831. },
  3832. "require-dev": {
  3833. "phpunit/phpunit": "^10.5"
  3834. },
  3835. "type": "library",
  3836. "extra": {
  3837. "branch-alias": {
  3838. "dev-main": "5.0-dev"
  3839. }
  3840. },
  3841. "autoload": {
  3842. "classmap": [
  3843. "src/"
  3844. ]
  3845. },
  3846. "notification-url": "https://packagist.org/downloads/",
  3847. "license": [
  3848. "BSD-3-Clause"
  3849. ],
  3850. "authors": [
  3851. {
  3852. "name": "Sebastian Bergmann",
  3853. "email": "sebastian@phpunit.de"
  3854. },
  3855. {
  3856. "name": "Jeff Welch",
  3857. "email": "whatthejeff@gmail.com"
  3858. },
  3859. {
  3860. "name": "Volker Dusch",
  3861. "email": "github@wallbash.com"
  3862. },
  3863. {
  3864. "name": "Bernhard Schussek",
  3865. "email": "bschussek@2bepublished.at"
  3866. }
  3867. ],
  3868. "description": "Provides the functionality to compare PHP values for equality",
  3869. "homepage": "https://github.com/sebastianbergmann/comparator",
  3870. "keywords": [
  3871. "comparator",
  3872. "compare",
  3873. "equality"
  3874. ],
  3875. "support": {
  3876. "issues": "https://github.com/sebastianbergmann/comparator/issues",
  3877. "security": "https://github.com/sebastianbergmann/comparator/security/policy",
  3878. "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3"
  3879. },
  3880. "funding": [
  3881. {
  3882. "url": "https://github.com/sebastianbergmann",
  3883. "type": "github"
  3884. }
  3885. ],
  3886. "time": "2024-10-18T14:56:07+00:00"
  3887. },
  3888. {
  3889. "name": "sebastian/complexity",
  3890. "version": "3.2.0",
  3891. "source": {
  3892. "type": "git",
  3893. "url": "https://github.com/sebastianbergmann/complexity.git",
  3894. "reference": "68ff824baeae169ec9f2137158ee529584553799"
  3895. },
  3896. "dist": {
  3897. "type": "zip",
  3898. "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
  3899. "reference": "68ff824baeae169ec9f2137158ee529584553799",
  3900. "shasum": ""
  3901. },
  3902. "require": {
  3903. "nikic/php-parser": "^4.18 || ^5.0",
  3904. "php": ">=8.1"
  3905. },
  3906. "require-dev": {
  3907. "phpunit/phpunit": "^10.0"
  3908. },
  3909. "type": "library",
  3910. "extra": {
  3911. "branch-alias": {
  3912. "dev-main": "3.2-dev"
  3913. }
  3914. },
  3915. "autoload": {
  3916. "classmap": [
  3917. "src/"
  3918. ]
  3919. },
  3920. "notification-url": "https://packagist.org/downloads/",
  3921. "license": [
  3922. "BSD-3-Clause"
  3923. ],
  3924. "authors": [
  3925. {
  3926. "name": "Sebastian Bergmann",
  3927. "email": "sebastian@phpunit.de",
  3928. "role": "lead"
  3929. }
  3930. ],
  3931. "description": "Library for calculating the complexity of PHP code units",
  3932. "homepage": "https://github.com/sebastianbergmann/complexity",
  3933. "support": {
  3934. "issues": "https://github.com/sebastianbergmann/complexity/issues",
  3935. "security": "https://github.com/sebastianbergmann/complexity/security/policy",
  3936. "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
  3937. },
  3938. "funding": [
  3939. {
  3940. "url": "https://github.com/sebastianbergmann",
  3941. "type": "github"
  3942. }
  3943. ],
  3944. "time": "2023-12-21T08:37:17+00:00"
  3945. },
  3946. {
  3947. "name": "sebastian/diff",
  3948. "version": "5.1.1",
  3949. "source": {
  3950. "type": "git",
  3951. "url": "https://github.com/sebastianbergmann/diff.git",
  3952. "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e"
  3953. },
  3954. "dist": {
  3955. "type": "zip",
  3956. "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e",
  3957. "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e",
  3958. "shasum": ""
  3959. },
  3960. "require": {
  3961. "php": ">=8.1"
  3962. },
  3963. "require-dev": {
  3964. "phpunit/phpunit": "^10.0",
  3965. "symfony/process": "^6.4"
  3966. },
  3967. "type": "library",
  3968. "extra": {
  3969. "branch-alias": {
  3970. "dev-main": "5.1-dev"
  3971. }
  3972. },
  3973. "autoload": {
  3974. "classmap": [
  3975. "src/"
  3976. ]
  3977. },
  3978. "notification-url": "https://packagist.org/downloads/",
  3979. "license": [
  3980. "BSD-3-Clause"
  3981. ],
  3982. "authors": [
  3983. {
  3984. "name": "Sebastian Bergmann",
  3985. "email": "sebastian@phpunit.de"
  3986. },
  3987. {
  3988. "name": "Kore Nordmann",
  3989. "email": "mail@kore-nordmann.de"
  3990. }
  3991. ],
  3992. "description": "Diff implementation",
  3993. "homepage": "https://github.com/sebastianbergmann/diff",
  3994. "keywords": [
  3995. "diff",
  3996. "udiff",
  3997. "unidiff",
  3998. "unified diff"
  3999. ],
  4000. "support": {
  4001. "issues": "https://github.com/sebastianbergmann/diff/issues",
  4002. "security": "https://github.com/sebastianbergmann/diff/security/policy",
  4003. "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1"
  4004. },
  4005. "funding": [
  4006. {
  4007. "url": "https://github.com/sebastianbergmann",
  4008. "type": "github"
  4009. }
  4010. ],
  4011. "time": "2024-03-02T07:15:17+00:00"
  4012. },
  4013. {
  4014. "name": "sebastian/environment",
  4015. "version": "6.1.0",
  4016. "source": {
  4017. "type": "git",
  4018. "url": "https://github.com/sebastianbergmann/environment.git",
  4019. "reference": "8074dbcd93529b357029f5cc5058fd3e43666984"
  4020. },
  4021. "dist": {
  4022. "type": "zip",
  4023. "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984",
  4024. "reference": "8074dbcd93529b357029f5cc5058fd3e43666984",
  4025. "shasum": ""
  4026. },
  4027. "require": {
  4028. "php": ">=8.1"
  4029. },
  4030. "require-dev": {
  4031. "phpunit/phpunit": "^10.0"
  4032. },
  4033. "suggest": {
  4034. "ext-posix": "*"
  4035. },
  4036. "type": "library",
  4037. "extra": {
  4038. "branch-alias": {
  4039. "dev-main": "6.1-dev"
  4040. }
  4041. },
  4042. "autoload": {
  4043. "classmap": [
  4044. "src/"
  4045. ]
  4046. },
  4047. "notification-url": "https://packagist.org/downloads/",
  4048. "license": [
  4049. "BSD-3-Clause"
  4050. ],
  4051. "authors": [
  4052. {
  4053. "name": "Sebastian Bergmann",
  4054. "email": "sebastian@phpunit.de"
  4055. }
  4056. ],
  4057. "description": "Provides functionality to handle HHVM/PHP environments",
  4058. "homepage": "https://github.com/sebastianbergmann/environment",
  4059. "keywords": [
  4060. "Xdebug",
  4061. "environment",
  4062. "hhvm"
  4063. ],
  4064. "support": {
  4065. "issues": "https://github.com/sebastianbergmann/environment/issues",
  4066. "security": "https://github.com/sebastianbergmann/environment/security/policy",
  4067. "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0"
  4068. },
  4069. "funding": [
  4070. {
  4071. "url": "https://github.com/sebastianbergmann",
  4072. "type": "github"
  4073. }
  4074. ],
  4075. "time": "2024-03-23T08:47:14+00:00"
  4076. },
  4077. {
  4078. "name": "sebastian/exporter",
  4079. "version": "5.1.2",
  4080. "source": {
  4081. "type": "git",
  4082. "url": "https://github.com/sebastianbergmann/exporter.git",
  4083. "reference": "955288482d97c19a372d3f31006ab3f37da47adf"
  4084. },
  4085. "dist": {
  4086. "type": "zip",
  4087. "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf",
  4088. "reference": "955288482d97c19a372d3f31006ab3f37da47adf",
  4089. "shasum": ""
  4090. },
  4091. "require": {
  4092. "ext-mbstring": "*",
  4093. "php": ">=8.1",
  4094. "sebastian/recursion-context": "^5.0"
  4095. },
  4096. "require-dev": {
  4097. "phpunit/phpunit": "^10.0"
  4098. },
  4099. "type": "library",
  4100. "extra": {
  4101. "branch-alias": {
  4102. "dev-main": "5.1-dev"
  4103. }
  4104. },
  4105. "autoload": {
  4106. "classmap": [
  4107. "src/"
  4108. ]
  4109. },
  4110. "notification-url": "https://packagist.org/downloads/",
  4111. "license": [
  4112. "BSD-3-Clause"
  4113. ],
  4114. "authors": [
  4115. {
  4116. "name": "Sebastian Bergmann",
  4117. "email": "sebastian@phpunit.de"
  4118. },
  4119. {
  4120. "name": "Jeff Welch",
  4121. "email": "whatthejeff@gmail.com"
  4122. },
  4123. {
  4124. "name": "Volker Dusch",
  4125. "email": "github@wallbash.com"
  4126. },
  4127. {
  4128. "name": "Adam Harvey",
  4129. "email": "aharvey@php.net"
  4130. },
  4131. {
  4132. "name": "Bernhard Schussek",
  4133. "email": "bschussek@gmail.com"
  4134. }
  4135. ],
  4136. "description": "Provides the functionality to export PHP variables for visualization",
  4137. "homepage": "https://www.github.com/sebastianbergmann/exporter",
  4138. "keywords": [
  4139. "export",
  4140. "exporter"
  4141. ],
  4142. "support": {
  4143. "issues": "https://github.com/sebastianbergmann/exporter/issues",
  4144. "security": "https://github.com/sebastianbergmann/exporter/security/policy",
  4145. "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2"
  4146. },
  4147. "funding": [
  4148. {
  4149. "url": "https://github.com/sebastianbergmann",
  4150. "type": "github"
  4151. }
  4152. ],
  4153. "time": "2024-03-02T07:17:12+00:00"
  4154. },
  4155. {
  4156. "name": "sebastian/global-state",
  4157. "version": "6.0.2",
  4158. "source": {
  4159. "type": "git",
  4160. "url": "https://github.com/sebastianbergmann/global-state.git",
  4161. "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9"
  4162. },
  4163. "dist": {
  4164. "type": "zip",
  4165. "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
  4166. "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
  4167. "shasum": ""
  4168. },
  4169. "require": {
  4170. "php": ">=8.1",
  4171. "sebastian/object-reflector": "^3.0",
  4172. "sebastian/recursion-context": "^5.0"
  4173. },
  4174. "require-dev": {
  4175. "ext-dom": "*",
  4176. "phpunit/phpunit": "^10.0"
  4177. },
  4178. "type": "library",
  4179. "extra": {
  4180. "branch-alias": {
  4181. "dev-main": "6.0-dev"
  4182. }
  4183. },
  4184. "autoload": {
  4185. "classmap": [
  4186. "src/"
  4187. ]
  4188. },
  4189. "notification-url": "https://packagist.org/downloads/",
  4190. "license": [
  4191. "BSD-3-Clause"
  4192. ],
  4193. "authors": [
  4194. {
  4195. "name": "Sebastian Bergmann",
  4196. "email": "sebastian@phpunit.de"
  4197. }
  4198. ],
  4199. "description": "Snapshotting of global state",
  4200. "homepage": "https://www.github.com/sebastianbergmann/global-state",
  4201. "keywords": [
  4202. "global state"
  4203. ],
  4204. "support": {
  4205. "issues": "https://github.com/sebastianbergmann/global-state/issues",
  4206. "security": "https://github.com/sebastianbergmann/global-state/security/policy",
  4207. "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2"
  4208. },
  4209. "funding": [
  4210. {
  4211. "url": "https://github.com/sebastianbergmann",
  4212. "type": "github"
  4213. }
  4214. ],
  4215. "time": "2024-03-02T07:19:19+00:00"
  4216. },
  4217. {
  4218. "name": "sebastian/lines-of-code",
  4219. "version": "2.0.2",
  4220. "source": {
  4221. "type": "git",
  4222. "url": "https://github.com/sebastianbergmann/lines-of-code.git",
  4223. "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
  4224. },
  4225. "dist": {
  4226. "type": "zip",
  4227. "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
  4228. "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
  4229. "shasum": ""
  4230. },
  4231. "require": {
  4232. "nikic/php-parser": "^4.18 || ^5.0",
  4233. "php": ">=8.1"
  4234. },
  4235. "require-dev": {
  4236. "phpunit/phpunit": "^10.0"
  4237. },
  4238. "type": "library",
  4239. "extra": {
  4240. "branch-alias": {
  4241. "dev-main": "2.0-dev"
  4242. }
  4243. },
  4244. "autoload": {
  4245. "classmap": [
  4246. "src/"
  4247. ]
  4248. },
  4249. "notification-url": "https://packagist.org/downloads/",
  4250. "license": [
  4251. "BSD-3-Clause"
  4252. ],
  4253. "authors": [
  4254. {
  4255. "name": "Sebastian Bergmann",
  4256. "email": "sebastian@phpunit.de",
  4257. "role": "lead"
  4258. }
  4259. ],
  4260. "description": "Library for counting the lines of code in PHP source code",
  4261. "homepage": "https://github.com/sebastianbergmann/lines-of-code",
  4262. "support": {
  4263. "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
  4264. "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
  4265. "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
  4266. },
  4267. "funding": [
  4268. {
  4269. "url": "https://github.com/sebastianbergmann",
  4270. "type": "github"
  4271. }
  4272. ],
  4273. "time": "2023-12-21T08:38:20+00:00"
  4274. },
  4275. {
  4276. "name": "sebastian/object-enumerator",
  4277. "version": "5.0.0",
  4278. "source": {
  4279. "type": "git",
  4280. "url": "https://github.com/sebastianbergmann/object-enumerator.git",
  4281. "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906"
  4282. },
  4283. "dist": {
  4284. "type": "zip",
  4285. "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906",
  4286. "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906",
  4287. "shasum": ""
  4288. },
  4289. "require": {
  4290. "php": ">=8.1",
  4291. "sebastian/object-reflector": "^3.0",
  4292. "sebastian/recursion-context": "^5.0"
  4293. },
  4294. "require-dev": {
  4295. "phpunit/phpunit": "^10.0"
  4296. },
  4297. "type": "library",
  4298. "extra": {
  4299. "branch-alias": {
  4300. "dev-main": "5.0-dev"
  4301. }
  4302. },
  4303. "autoload": {
  4304. "classmap": [
  4305. "src/"
  4306. ]
  4307. },
  4308. "notification-url": "https://packagist.org/downloads/",
  4309. "license": [
  4310. "BSD-3-Clause"
  4311. ],
  4312. "authors": [
  4313. {
  4314. "name": "Sebastian Bergmann",
  4315. "email": "sebastian@phpunit.de"
  4316. }
  4317. ],
  4318. "description": "Traverses array structures and object graphs to enumerate all referenced objects",
  4319. "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
  4320. "support": {
  4321. "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
  4322. "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0"
  4323. },
  4324. "funding": [
  4325. {
  4326. "url": "https://github.com/sebastianbergmann",
  4327. "type": "github"
  4328. }
  4329. ],
  4330. "time": "2023-02-03T07:08:32+00:00"
  4331. },
  4332. {
  4333. "name": "sebastian/object-reflector",
  4334. "version": "3.0.0",
  4335. "source": {
  4336. "type": "git",
  4337. "url": "https://github.com/sebastianbergmann/object-reflector.git",
  4338. "reference": "24ed13d98130f0e7122df55d06c5c4942a577957"
  4339. },
  4340. "dist": {
  4341. "type": "zip",
  4342. "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957",
  4343. "reference": "24ed13d98130f0e7122df55d06c5c4942a577957",
  4344. "shasum": ""
  4345. },
  4346. "require": {
  4347. "php": ">=8.1"
  4348. },
  4349. "require-dev": {
  4350. "phpunit/phpunit": "^10.0"
  4351. },
  4352. "type": "library",
  4353. "extra": {
  4354. "branch-alias": {
  4355. "dev-main": "3.0-dev"
  4356. }
  4357. },
  4358. "autoload": {
  4359. "classmap": [
  4360. "src/"
  4361. ]
  4362. },
  4363. "notification-url": "https://packagist.org/downloads/",
  4364. "license": [
  4365. "BSD-3-Clause"
  4366. ],
  4367. "authors": [
  4368. {
  4369. "name": "Sebastian Bergmann",
  4370. "email": "sebastian@phpunit.de"
  4371. }
  4372. ],
  4373. "description": "Allows reflection of object attributes, including inherited and non-public ones",
  4374. "homepage": "https://github.com/sebastianbergmann/object-reflector/",
  4375. "support": {
  4376. "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
  4377. "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0"
  4378. },
  4379. "funding": [
  4380. {
  4381. "url": "https://github.com/sebastianbergmann",
  4382. "type": "github"
  4383. }
  4384. ],
  4385. "time": "2023-02-03T07:06:18+00:00"
  4386. },
  4387. {
  4388. "name": "sebastian/recursion-context",
  4389. "version": "5.0.0",
  4390. "source": {
  4391. "type": "git",
  4392. "url": "https://github.com/sebastianbergmann/recursion-context.git",
  4393. "reference": "05909fb5bc7df4c52992396d0116aed689f93712"
  4394. },
  4395. "dist": {
  4396. "type": "zip",
  4397. "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712",
  4398. "reference": "05909fb5bc7df4c52992396d0116aed689f93712",
  4399. "shasum": ""
  4400. },
  4401. "require": {
  4402. "php": ">=8.1"
  4403. },
  4404. "require-dev": {
  4405. "phpunit/phpunit": "^10.0"
  4406. },
  4407. "type": "library",
  4408. "extra": {
  4409. "branch-alias": {
  4410. "dev-main": "5.0-dev"
  4411. }
  4412. },
  4413. "autoload": {
  4414. "classmap": [
  4415. "src/"
  4416. ]
  4417. },
  4418. "notification-url": "https://packagist.org/downloads/",
  4419. "license": [
  4420. "BSD-3-Clause"
  4421. ],
  4422. "authors": [
  4423. {
  4424. "name": "Sebastian Bergmann",
  4425. "email": "sebastian@phpunit.de"
  4426. },
  4427. {
  4428. "name": "Jeff Welch",
  4429. "email": "whatthejeff@gmail.com"
  4430. },
  4431. {
  4432. "name": "Adam Harvey",
  4433. "email": "aharvey@php.net"
  4434. }
  4435. ],
  4436. "description": "Provides functionality to recursively process PHP variables",
  4437. "homepage": "https://github.com/sebastianbergmann/recursion-context",
  4438. "support": {
  4439. "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
  4440. "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0"
  4441. },
  4442. "funding": [
  4443. {
  4444. "url": "https://github.com/sebastianbergmann",
  4445. "type": "github"
  4446. }
  4447. ],
  4448. "time": "2023-02-03T07:05:40+00:00"
  4449. },
  4450. {
  4451. "name": "sebastian/type",
  4452. "version": "4.0.0",
  4453. "source": {
  4454. "type": "git",
  4455. "url": "https://github.com/sebastianbergmann/type.git",
  4456. "reference": "462699a16464c3944eefc02ebdd77882bd3925bf"
  4457. },
  4458. "dist": {
  4459. "type": "zip",
  4460. "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf",
  4461. "reference": "462699a16464c3944eefc02ebdd77882bd3925bf",
  4462. "shasum": ""
  4463. },
  4464. "require": {
  4465. "php": ">=8.1"
  4466. },
  4467. "require-dev": {
  4468. "phpunit/phpunit": "^10.0"
  4469. },
  4470. "type": "library",
  4471. "extra": {
  4472. "branch-alias": {
  4473. "dev-main": "4.0-dev"
  4474. }
  4475. },
  4476. "autoload": {
  4477. "classmap": [
  4478. "src/"
  4479. ]
  4480. },
  4481. "notification-url": "https://packagist.org/downloads/",
  4482. "license": [
  4483. "BSD-3-Clause"
  4484. ],
  4485. "authors": [
  4486. {
  4487. "name": "Sebastian Bergmann",
  4488. "email": "sebastian@phpunit.de",
  4489. "role": "lead"
  4490. }
  4491. ],
  4492. "description": "Collection of value objects that represent the types of the PHP type system",
  4493. "homepage": "https://github.com/sebastianbergmann/type",
  4494. "support": {
  4495. "issues": "https://github.com/sebastianbergmann/type/issues",
  4496. "source": "https://github.com/sebastianbergmann/type/tree/4.0.0"
  4497. },
  4498. "funding": [
  4499. {
  4500. "url": "https://github.com/sebastianbergmann",
  4501. "type": "github"
  4502. }
  4503. ],
  4504. "time": "2023-02-03T07:10:45+00:00"
  4505. },
  4506. {
  4507. "name": "sebastian/version",
  4508. "version": "4.0.1",
  4509. "source": {
  4510. "type": "git",
  4511. "url": "https://github.com/sebastianbergmann/version.git",
  4512. "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17"
  4513. },
  4514. "dist": {
  4515. "type": "zip",
  4516. "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17",
  4517. "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17",
  4518. "shasum": ""
  4519. },
  4520. "require": {
  4521. "php": ">=8.1"
  4522. },
  4523. "type": "library",
  4524. "extra": {
  4525. "branch-alias": {
  4526. "dev-main": "4.0-dev"
  4527. }
  4528. },
  4529. "autoload": {
  4530. "classmap": [
  4531. "src/"
  4532. ]
  4533. },
  4534. "notification-url": "https://packagist.org/downloads/",
  4535. "license": [
  4536. "BSD-3-Clause"
  4537. ],
  4538. "authors": [
  4539. {
  4540. "name": "Sebastian Bergmann",
  4541. "email": "sebastian@phpunit.de",
  4542. "role": "lead"
  4543. }
  4544. ],
  4545. "description": "Library that helps with managing the version number of Git-hosted PHP projects",
  4546. "homepage": "https://github.com/sebastianbergmann/version",
  4547. "support": {
  4548. "issues": "https://github.com/sebastianbergmann/version/issues",
  4549. "source": "https://github.com/sebastianbergmann/version/tree/4.0.1"
  4550. },
  4551. "funding": [
  4552. {
  4553. "url": "https://github.com/sebastianbergmann",
  4554. "type": "github"
  4555. }
  4556. ],
  4557. "time": "2023-02-07T11:34:05+00:00"
  4558. },
  4559. {
  4560. "name": "theseer/tokenizer",
  4561. "version": "1.2.3",
  4562. "source": {
  4563. "type": "git",
  4564. "url": "https://github.com/theseer/tokenizer.git",
  4565. "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
  4566. },
  4567. "dist": {
  4568. "type": "zip",
  4569. "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
  4570. "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
  4571. "shasum": ""
  4572. },
  4573. "require": {
  4574. "ext-dom": "*",
  4575. "ext-tokenizer": "*",
  4576. "ext-xmlwriter": "*",
  4577. "php": "^7.2 || ^8.0"
  4578. },
  4579. "type": "library",
  4580. "autoload": {
  4581. "classmap": [
  4582. "src/"
  4583. ]
  4584. },
  4585. "notification-url": "https://packagist.org/downloads/",
  4586. "license": [
  4587. "BSD-3-Clause"
  4588. ],
  4589. "authors": [
  4590. {
  4591. "name": "Arne Blankerts",
  4592. "email": "arne@blankerts.de",
  4593. "role": "Developer"
  4594. }
  4595. ],
  4596. "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
  4597. "support": {
  4598. "issues": "https://github.com/theseer/tokenizer/issues",
  4599. "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
  4600. },
  4601. "funding": [
  4602. {
  4603. "url": "https://github.com/theseer",
  4604. "type": "github"
  4605. }
  4606. ],
  4607. "time": "2024-03-03T12:36:25+00:00"
  4608. }
  4609. ],
  4610. "packages-dev": [],
  4611. "aliases": [],
  4612. "minimum-stability": "stable",
  4613. "stability-flags": {},
  4614. "prefer-stable": true,
  4615. "prefer-lowest": false,
  4616. "platform": {
  4617. "php": ">=8.1",
  4618. "ext-dom": "*",
  4619. "ext-json": "*",
  4620. "ext-libxml": "*",
  4621. "ext-mbstring": "*",
  4622. "ext-xml": "*",
  4623. "ext-xmlwriter": "*"
  4624. },
  4625. "platform-dev": {},
  4626. "platform-overrides": {
  4627. "php": "8.1.0"
  4628. },
  4629. "plugin-api-version": "2.6.0"
  4630. }
  4631. phpunit/phpunit: 10.5.40
  4632. myclabs/deep-copy: 1.12.1
  4633. nikic/php-parser: v5.3.1
  4634. phar-io/manifest: 2.0.4
  4635. phar-io/version: 3.2.1
  4636. phpunit/php-code-coverage: 10.1.16
  4637. phpunit/php-file-iterator: 4.1.0
  4638. phpunit/php-invoker: 4.0.0
  4639. phpunit/php-text-template: 3.0.1
  4640. phpunit/php-timer: 6.0.0
  4641. sebastian/cli-parser: 2.0.1
  4642. sebastian/code-unit: 2.0.0
  4643. sebastian/code-unit-reverse-lookup: 3.0.0
  4644. sebastian/comparator: 5.0.3
  4645. sebastian/complexity: 3.2.0
  4646. sebastian/diff: 5.1.1
  4647. sebastian/environment: 6.1.0
  4648. sebastian/exporter: 5.1.2
  4649. sebastian/global-state: 6.0.2
  4650. sebastian/lines-of-code: 2.0.2
  4651. sebastian/object-enumerator: 5.0.0
  4652. sebastian/object-reflector: 3.0.0
  4653. sebastian/recursion-context: 5.0.0
  4654. sebastian/type: 4.0.0
  4655. sebastian/version: 4.0.1
  4656. theseer/tokenizer: 1.2.3
  4657. <?php
  4658. namespace PHPUnitPHAR\DeepCopy;
  4659. use ArrayObject;
  4660. use DateInterval;
  4661. use DatePeriod;
  4662. use DateTimeInterface;
  4663. use DateTimeZone;
  4664. use PHPUnitPHAR\DeepCopy\Exception\CloneException;
  4665. use PHPUnitPHAR\DeepCopy\Filter\ChainableFilter;
  4666. use PHPUnitPHAR\DeepCopy\Filter\Filter;
  4667. use PHPUnitPHAR\DeepCopy\Matcher\Matcher;
  4668. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  4669. use PHPUnitPHAR\DeepCopy\TypeFilter\Date\DateIntervalFilter;
  4670. use PHPUnitPHAR\DeepCopy\TypeFilter\Date\DatePeriodFilter;
  4671. use PHPUnitPHAR\DeepCopy\TypeFilter\Spl\ArrayObjectFilter;
  4672. use PHPUnitPHAR\DeepCopy\TypeFilter\Spl\SplDoublyLinkedListFilter;
  4673. use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
  4674. use PHPUnitPHAR\DeepCopy\TypeMatcher\TypeMatcher;
  4675. use ReflectionObject;
  4676. use ReflectionProperty;
  4677. use SplDoublyLinkedList;
  4678. /**
  4679. * @final
  4680. */
  4681. class DeepCopy
  4682. {
  4683. /**
  4684. * @var object[] List of objects copied.
  4685. */
  4686. private $hashMap = [];
  4687. /**
  4688. * Filters to apply.
  4689. *
  4690. * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
  4691. */
  4692. private $filters = [];
  4693. /**
  4694. * Type Filters to apply.
  4695. *
  4696. * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
  4697. */
  4698. private $typeFilters = [];
  4699. /**
  4700. * @var bool
  4701. */
  4702. private $skipUncloneable = \false;
  4703. /**
  4704. * @var bool
  4705. */
  4706. private $useCloneMethod;
  4707. /**
  4708. * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
  4709. * instead of the regular deep cloning.
  4710. */
  4711. public function __construct($useCloneMethod = \false)
  4712. {
  4713. $this->useCloneMethod = $useCloneMethod;
  4714. $this->addTypeFilter(new ArrayObjectFilter($this), new TypeMatcher(ArrayObject::class));
  4715. $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class));
  4716. $this->addTypeFilter(new DatePeriodFilter(), new TypeMatcher(DatePeriod::class));
  4717. $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class));
  4718. }
  4719. /**
  4720. * If enabled, will not throw an exception when coming across an uncloneable property.
  4721. *
  4722. * @param $skipUncloneable
  4723. *
  4724. * @return $this
  4725. */
  4726. public function skipUncloneable($skipUncloneable = \true)
  4727. {
  4728. $this->skipUncloneable = $skipUncloneable;
  4729. return $this;
  4730. }
  4731. /**
  4732. * Deep copies the given object.
  4733. *
  4734. * @param mixed $object
  4735. *
  4736. * @return mixed
  4737. */
  4738. public function copy($object)
  4739. {
  4740. $this->hashMap = [];
  4741. return $this->recursiveCopy($object);
  4742. }
  4743. public function addFilter(Filter $filter, Matcher $matcher)
  4744. {
  4745. $this->filters[] = ['matcher' => $matcher, 'filter' => $filter];
  4746. }
  4747. public function prependFilter(Filter $filter, Matcher $matcher)
  4748. {
  4749. array_unshift($this->filters, ['matcher' => $matcher, 'filter' => $filter]);
  4750. }
  4751. public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
  4752. {
  4753. $this->typeFilters[] = ['matcher' => $matcher, 'filter' => $filter];
  4754. }
  4755. private function recursiveCopy($var)
  4756. {
  4757. // Matches Type Filter
  4758. if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) {
  4759. return $filter->apply($var);
  4760. }
  4761. // Resource
  4762. if (is_resource($var)) {
  4763. return $var;
  4764. }
  4765. // Array
  4766. if (is_array($var)) {
  4767. return $this->copyArray($var);
  4768. }
  4769. // Scalar
  4770. if (!is_object($var)) {
  4771. return $var;
  4772. }
  4773. // Enum
  4774. if (\PHP_VERSION_ID >= 80100 && enum_exists(get_class($var))) {
  4775. return $var;
  4776. }
  4777. // Object
  4778. return $this->copyObject($var);
  4779. }
  4780. /**
  4781. * Copy an array
  4782. * @param array $array
  4783. * @return array
  4784. */
  4785. private function copyArray(array $array)
  4786. {
  4787. foreach ($array as $key => $value) {
  4788. $array[$key] = $this->recursiveCopy($value);
  4789. }
  4790. return $array;
  4791. }
  4792. /**
  4793. * Copies an object.
  4794. *
  4795. * @param object $object
  4796. *
  4797. * @throws CloneException
  4798. *
  4799. * @return object
  4800. */
  4801. private function copyObject($object)
  4802. {
  4803. $objectHash = spl_object_hash($object);
  4804. if (isset($this->hashMap[$objectHash])) {
  4805. return $this->hashMap[$objectHash];
  4806. }
  4807. $reflectedObject = new ReflectionObject($object);
  4808. $isCloneable = $reflectedObject->isCloneable();
  4809. if (\false === $isCloneable) {
  4810. if ($this->skipUncloneable) {
  4811. $this->hashMap[$objectHash] = $object;
  4812. return $object;
  4813. }
  4814. throw new CloneException(sprintf('The class "%s" is not cloneable.', $reflectedObject->getName()));
  4815. }
  4816. $newObject = clone $object;
  4817. $this->hashMap[$objectHash] = $newObject;
  4818. if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) {
  4819. return $newObject;
  4820. }
  4821. if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) {
  4822. return $newObject;
  4823. }
  4824. foreach (ReflectionHelper::getProperties($reflectedObject) as $property) {
  4825. $this->copyObjectProperty($newObject, $property);
  4826. }
  4827. return $newObject;
  4828. }
  4829. private function copyObjectProperty($object, ReflectionProperty $property)
  4830. {
  4831. // Ignore static properties
  4832. if ($property->isStatic()) {
  4833. return;
  4834. }
  4835. // Ignore readonly properties
  4836. if (method_exists($property, 'isReadOnly') && $property->isReadOnly()) {
  4837. return;
  4838. }
  4839. // Apply the filters
  4840. foreach ($this->filters as $item) {
  4841. /** @var Matcher $matcher */
  4842. $matcher = $item['matcher'];
  4843. /** @var Filter $filter */
  4844. $filter = $item['filter'];
  4845. if ($matcher->matches($object, $property->getName())) {
  4846. $filter->apply($object, $property->getName(), function ($object) {
  4847. return $this->recursiveCopy($object);
  4848. });
  4849. if ($filter instanceof ChainableFilter) {
  4850. continue;
  4851. }
  4852. // If a filter matches, we stop processing this property
  4853. return;
  4854. }
  4855. }
  4856. $property->setAccessible(\true);
  4857. // Ignore uninitialized properties (for PHP >7.4)
  4858. if (method_exists($property, 'isInitialized') && !$property->isInitialized($object)) {
  4859. return;
  4860. }
  4861. $propertyValue = $property->getValue($object);
  4862. // Copy the property
  4863. $property->setValue($object, $this->recursiveCopy($propertyValue));
  4864. }
  4865. /**
  4866. * Returns first filter that matches variable, `null` if no such filter found.
  4867. *
  4868. * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and
  4869. * 'matcher' with value of type {@see TypeMatcher}
  4870. * @param mixed $var
  4871. *
  4872. * @return TypeFilter|null
  4873. */
  4874. private function getFirstMatchedTypeFilter(array $filterRecords, $var)
  4875. {
  4876. $matched = $this->first($filterRecords, function (array $record) use ($var) {
  4877. /* @var TypeMatcher $matcher */
  4878. $matcher = $record['matcher'];
  4879. return $matcher->matches($var);
  4880. });
  4881. return isset($matched) ? $matched['filter'] : null;
  4882. }
  4883. /**
  4884. * Returns first element that matches predicate, `null` if no such element found.
  4885. *
  4886. * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
  4887. * @param callable $predicate Predicate arguments are: element.
  4888. *
  4889. * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher'
  4890. * with value of type {@see TypeMatcher} or `null`.
  4891. */
  4892. private function first(array $elements, callable $predicate)
  4893. {
  4894. foreach ($elements as $element) {
  4895. if (call_user_func($predicate, $element)) {
  4896. return $element;
  4897. }
  4898. }
  4899. return null;
  4900. }
  4901. }
  4902. <?php
  4903. namespace PHPUnitPHAR\DeepCopy\Exception;
  4904. use UnexpectedValueException;
  4905. class CloneException extends UnexpectedValueException
  4906. {
  4907. }
  4908. <?php
  4909. namespace PHPUnitPHAR\DeepCopy\Exception;
  4910. use ReflectionException;
  4911. class PropertyException extends ReflectionException
  4912. {
  4913. }
  4914. <?php
  4915. namespace PHPUnitPHAR\DeepCopy\Filter;
  4916. /**
  4917. * Defines a decorator filter that will not stop the chain of filters.
  4918. */
  4919. class ChainableFilter implements Filter
  4920. {
  4921. /**
  4922. * @var Filter
  4923. */
  4924. protected $filter;
  4925. public function __construct(Filter $filter)
  4926. {
  4927. $this->filter = $filter;
  4928. }
  4929. public function apply($object, $property, $objectCopier)
  4930. {
  4931. $this->filter->apply($object, $property, $objectCopier);
  4932. }
  4933. }
  4934. <?php
  4935. namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
  4936. use PHPUnitPHAR\DeepCopy\Filter\Filter;
  4937. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  4938. /**
  4939. * @final
  4940. */
  4941. class DoctrineCollectionFilter implements Filter
  4942. {
  4943. /**
  4944. * Copies the object property doctrine collection.
  4945. *
  4946. * {@inheritdoc}
  4947. */
  4948. public function apply($object, $property, $objectCopier)
  4949. {
  4950. $reflectionProperty = ReflectionHelper::getProperty($object, $property);
  4951. $reflectionProperty->setAccessible(\true);
  4952. $oldCollection = $reflectionProperty->getValue($object);
  4953. $newCollection = $oldCollection->map(function ($item) use ($objectCopier) {
  4954. return $objectCopier($item);
  4955. });
  4956. $reflectionProperty->setValue($object, $newCollection);
  4957. }
  4958. }
  4959. <?php
  4960. namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
  4961. use PHPUnitPHAR\DeepCopy\Filter\Filter;
  4962. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  4963. use PHPUnitPHAR\Doctrine\Common\Collections\ArrayCollection;
  4964. /**
  4965. * @final
  4966. */
  4967. class DoctrineEmptyCollectionFilter implements Filter
  4968. {
  4969. /**
  4970. * Sets the object property to an empty doctrine collection.
  4971. *
  4972. * @param object $object
  4973. * @param string $property
  4974. * @param callable $objectCopier
  4975. */
  4976. public function apply($object, $property, $objectCopier)
  4977. {
  4978. $reflectionProperty = ReflectionHelper::getProperty($object, $property);
  4979. $reflectionProperty->setAccessible(\true);
  4980. $reflectionProperty->setValue($object, new ArrayCollection());
  4981. }
  4982. }
  4983. <?php
  4984. namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
  4985. use PHPUnitPHAR\DeepCopy\Filter\Filter;
  4986. /**
  4987. * @final
  4988. */
  4989. class DoctrineProxyFilter implements Filter
  4990. {
  4991. /**
  4992. * Triggers the magic method __load() on a Doctrine Proxy class to load the
  4993. * actual entity from the database.
  4994. *
  4995. * {@inheritdoc}
  4996. */
  4997. public function apply($object, $property, $objectCopier)
  4998. {
  4999. $object->__load();
  5000. }
  5001. }
  5002. <?php
  5003. namespace PHPUnitPHAR\DeepCopy\Filter;
  5004. /**
  5005. * Filter to apply to a property while copying an object
  5006. */
  5007. interface Filter
  5008. {
  5009. /**
  5010. * Applies the filter to the object.
  5011. *
  5012. * @param object $object
  5013. * @param string $property
  5014. * @param callable $objectCopier
  5015. */
  5016. public function apply($object, $property, $objectCopier);
  5017. }
  5018. <?php
  5019. namespace PHPUnitPHAR\DeepCopy\Filter;
  5020. class KeepFilter implements Filter
  5021. {
  5022. /**
  5023. * Keeps the value of the object property.
  5024. *
  5025. * {@inheritdoc}
  5026. */
  5027. public function apply($object, $property, $objectCopier)
  5028. {
  5029. // Nothing to do
  5030. }
  5031. }
  5032. <?php
  5033. namespace PHPUnitPHAR\DeepCopy\Filter;
  5034. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  5035. /**
  5036. * @final
  5037. */
  5038. class ReplaceFilter implements Filter
  5039. {
  5040. /**
  5041. * @var callable
  5042. */
  5043. protected $callback;
  5044. /**
  5045. * @param callable $callable Will be called to get the new value for each property to replace
  5046. */
  5047. public function __construct(callable $callable)
  5048. {
  5049. $this->callback = $callable;
  5050. }
  5051. /**
  5052. * Replaces the object property by the result of the callback called with the object property.
  5053. *
  5054. * {@inheritdoc}
  5055. */
  5056. public function apply($object, $property, $objectCopier)
  5057. {
  5058. $reflectionProperty = ReflectionHelper::getProperty($object, $property);
  5059. $reflectionProperty->setAccessible(\true);
  5060. $value = call_user_func($this->callback, $reflectionProperty->getValue($object));
  5061. $reflectionProperty->setValue($object, $value);
  5062. }
  5063. }
  5064. <?php
  5065. namespace PHPUnitPHAR\DeepCopy\Filter;
  5066. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  5067. /**
  5068. * @final
  5069. */
  5070. class SetNullFilter implements Filter
  5071. {
  5072. /**
  5073. * Sets the object property to null.
  5074. *
  5075. * {@inheritdoc}
  5076. */
  5077. public function apply($object, $property, $objectCopier)
  5078. {
  5079. $reflectionProperty = ReflectionHelper::getProperty($object, $property);
  5080. $reflectionProperty->setAccessible(\true);
  5081. $reflectionProperty->setValue($object, null);
  5082. }
  5083. }
  5084. <?php
  5085. namespace PHPUnitPHAR\DeepCopy\Matcher\Doctrine;
  5086. use PHPUnitPHAR\DeepCopy\Matcher\Matcher;
  5087. use PHPUnitPHAR\Doctrine\Persistence\Proxy;
  5088. /**
  5089. * @final
  5090. */
  5091. class DoctrineProxyMatcher implements Matcher
  5092. {
  5093. /**
  5094. * Matches a Doctrine Proxy class.
  5095. *
  5096. * {@inheritdoc}
  5097. */
  5098. public function matches($object, $property)
  5099. {
  5100. return $object instanceof Proxy;
  5101. }
  5102. }
  5103. <?php
  5104. namespace PHPUnitPHAR\DeepCopy\Matcher;
  5105. interface Matcher
  5106. {
  5107. /**
  5108. * @param object $object
  5109. * @param string $property
  5110. *
  5111. * @return boolean
  5112. */
  5113. public function matches($object, $property);
  5114. }
  5115. <?php
  5116. namespace PHPUnitPHAR\DeepCopy\Matcher;
  5117. /**
  5118. * @final
  5119. */
  5120. class PropertyMatcher implements Matcher
  5121. {
  5122. /**
  5123. * @var string
  5124. */
  5125. private $class;
  5126. /**
  5127. * @var string
  5128. */
  5129. private $property;
  5130. /**
  5131. * @param string $class Class name
  5132. * @param string $property Property name
  5133. */
  5134. public function __construct($class, $property)
  5135. {
  5136. $this->class = $class;
  5137. $this->property = $property;
  5138. }
  5139. /**
  5140. * Matches a specific property of a specific class.
  5141. *
  5142. * {@inheritdoc}
  5143. */
  5144. public function matches($object, $property)
  5145. {
  5146. return $object instanceof $this->class && $property == $this->property;
  5147. }
  5148. }
  5149. <?php
  5150. namespace PHPUnitPHAR\DeepCopy\Matcher;
  5151. /**
  5152. * @final
  5153. */
  5154. class PropertyNameMatcher implements Matcher
  5155. {
  5156. /**
  5157. * @var string
  5158. */
  5159. private $property;
  5160. /**
  5161. * @param string $property Property name
  5162. */
  5163. public function __construct($property)
  5164. {
  5165. $this->property = $property;
  5166. }
  5167. /**
  5168. * Matches a property by its name.
  5169. *
  5170. * {@inheritdoc}
  5171. */
  5172. public function matches($object, $property)
  5173. {
  5174. return $property == $this->property;
  5175. }
  5176. }
  5177. <?php
  5178. namespace PHPUnitPHAR\DeepCopy\Matcher;
  5179. use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
  5180. use ReflectionException;
  5181. /**
  5182. * Matches a property by its type.
  5183. *
  5184. * It is recommended to use {@see DeepCopy\TypeFilter\TypeFilter} instead, as it applies on all occurrences
  5185. * of given type in copied context (eg. array elements), not just on object properties.
  5186. *
  5187. * @final
  5188. */
  5189. class PropertyTypeMatcher implements Matcher
  5190. {
  5191. /**
  5192. * @var string
  5193. */
  5194. private $propertyType;
  5195. /**
  5196. * @param string $propertyType Property type
  5197. */
  5198. public function __construct($propertyType)
  5199. {
  5200. $this->propertyType = $propertyType;
  5201. }
  5202. /**
  5203. * {@inheritdoc}
  5204. */
  5205. public function matches($object, $property)
  5206. {
  5207. try {
  5208. $reflectionProperty = ReflectionHelper::getProperty($object, $property);
  5209. } catch (ReflectionException $exception) {
  5210. return \false;
  5211. }
  5212. $reflectionProperty->setAccessible(\true);
  5213. // Uninitialized properties (for PHP >7.4)
  5214. if (method_exists($reflectionProperty, 'isInitialized') && !$reflectionProperty->isInitialized($object)) {
  5215. // null instanceof $this->propertyType
  5216. return \false;
  5217. }
  5218. return $reflectionProperty->getValue($object) instanceof $this->propertyType;
  5219. }
  5220. }
  5221. <?php
  5222. namespace PHPUnitPHAR\DeepCopy\Reflection;
  5223. use PHPUnitPHAR\DeepCopy\Exception\PropertyException;
  5224. use ReflectionClass;
  5225. use ReflectionException;
  5226. use ReflectionObject;
  5227. use ReflectionProperty;
  5228. class ReflectionHelper
  5229. {
  5230. /**
  5231. * Retrieves all properties (including private ones), from object and all its ancestors.
  5232. *
  5233. * Standard \ReflectionClass->getProperties() does not return private properties from ancestor classes.
  5234. *
  5235. * @author muratyaman@gmail.com
  5236. * @see http://php.net/manual/en/reflectionclass.getproperties.php
  5237. *
  5238. * @param ReflectionClass $ref
  5239. *
  5240. * @return ReflectionProperty[]
  5241. */
  5242. public static function getProperties(ReflectionClass $ref)
  5243. {
  5244. $props = $ref->getProperties();
  5245. $propsArr = array();
  5246. foreach ($props as $prop) {
  5247. $propertyName = $prop->getName();
  5248. $propsArr[$propertyName] = $prop;
  5249. }
  5250. if ($parentClass = $ref->getParentClass()) {
  5251. $parentPropsArr = self::getProperties($parentClass);
  5252. foreach ($propsArr as $key => $property) {
  5253. $parentPropsArr[$key] = $property;
  5254. }
  5255. return $parentPropsArr;
  5256. }
  5257. return $propsArr;
  5258. }
  5259. /**
  5260. * Retrieves property by name from object and all its ancestors.
  5261. *
  5262. * @param object|string $object
  5263. * @param string $name
  5264. *
  5265. * @throws PropertyException
  5266. * @throws ReflectionException
  5267. *
  5268. * @return ReflectionProperty
  5269. */
  5270. public static function getProperty($object, $name)
  5271. {
  5272. $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object);
  5273. if ($reflection->hasProperty($name)) {
  5274. return $reflection->getProperty($name);
  5275. }
  5276. if ($parentClass = $reflection->getParentClass()) {
  5277. return self::getProperty($parentClass->getName(), $name);
  5278. }
  5279. throw new PropertyException(sprintf('The class "%s" doesn\'t have a property with the given name: "%s".', is_object($object) ? get_class($object) : $object, $name));
  5280. }
  5281. }
  5282. <?php
  5283. namespace PHPUnitPHAR\DeepCopy\TypeFilter\Date;
  5284. use DateInterval;
  5285. use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
  5286. /**
  5287. * @final
  5288. *
  5289. * @deprecated Will be removed in 2.0. This filter will no longer be necessary in PHP 7.1+.
  5290. */
  5291. class DateIntervalFilter implements TypeFilter
  5292. {
  5293. /**
  5294. * {@inheritdoc}
  5295. *
  5296. * @param DateInterval $element
  5297. *
  5298. * @see http://news.php.net/php.bugs/205076
  5299. */
  5300. public function apply($element)
  5301. {
  5302. $copy = new DateInterval('P0D');
  5303. foreach ($element as $propertyName => $propertyValue) {
  5304. $copy->{$propertyName} = $propertyValue;
  5305. }
  5306. return $copy;
  5307. }
  5308. }
  5309. <?php
  5310. namespace PHPUnitPHAR\DeepCopy\TypeFilter\Date;
  5311. use DatePeriod;
  5312. use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
  5313. /**
  5314. * @final
  5315. */
  5316. class DatePeriodFilter implements TypeFilter
  5317. {
  5318. /**
  5319. * {@inheritdoc}
  5320. *
  5321. * @param DatePeriod $element
  5322. *
  5323. * @see http://news.php.net/php.bugs/205076
  5324. */
  5325. public function apply($element)
  5326. {
  5327. $options = 0;
  5328. if (\PHP_VERSION_ID >= 80200 && $element->include_end_date) {
  5329. $options |= DatePeriod::INCLUDE_END_DATE;
  5330. }
  5331. if (!$element->include_start_date) {
  5332. $options |= DatePeriod::EXCLUDE_START_DATE;
  5333. }
  5334. if ($element->getEndDate()) {
  5335. return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getEndDate(), $options);
  5336. }
  5337. if (\PHP_VERSION_ID >= 70217) {
  5338. $recurrences = $element->getRecurrences();
  5339. } else {
  5340. $recurrences = $element->recurrences - $element->include_start_date;
  5341. }
  5342. return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $recurrences, $options);
  5343. }
  5344. }
  5345. <?php
  5346. namespace PHPUnitPHAR\DeepCopy\TypeFilter;
  5347. /**
  5348. * @final
  5349. */
  5350. class ReplaceFilter implements TypeFilter
  5351. {
  5352. /**
  5353. * @var callable
  5354. */
  5355. protected $callback;
  5356. /**
  5357. * @param callable $callable Will be called to get the new value for each element to replace
  5358. */
  5359. public function __construct(callable $callable)
  5360. {
  5361. $this->callback = $callable;
  5362. }
  5363. /**
  5364. * {@inheritdoc}
  5365. */
  5366. public function apply($element)
  5367. {
  5368. return call_user_func($this->callback, $element);
  5369. }
  5370. }
  5371. <?php
  5372. namespace PHPUnitPHAR\DeepCopy\TypeFilter;
  5373. /**
  5374. * @final
  5375. */
  5376. class ShallowCopyFilter implements TypeFilter
  5377. {
  5378. /**
  5379. * {@inheritdoc}
  5380. */
  5381. public function apply($element)
  5382. {
  5383. return clone $element;
  5384. }
  5385. }
  5386. <?php
  5387. namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
  5388. use PHPUnitPHAR\DeepCopy\DeepCopy;
  5389. use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
  5390. /**
  5391. * In PHP 7.4 the storage of an ArrayObject isn't returned as
  5392. * ReflectionProperty. So we deep copy its array copy.
  5393. */
  5394. final class ArrayObjectFilter implements TypeFilter
  5395. {
  5396. /**
  5397. * @var DeepCopy
  5398. */
  5399. private $copier;
  5400. public function __construct(DeepCopy $copier)
  5401. {
  5402. $this->copier = $copier;
  5403. }
  5404. /**
  5405. * {@inheritdoc}
  5406. */
  5407. public function apply($arrayObject)
  5408. {
  5409. $clone = clone $arrayObject;
  5410. foreach ($arrayObject->getArrayCopy() as $k => $v) {
  5411. $clone->offsetSet($k, $this->copier->copy($v));
  5412. }
  5413. return $clone;
  5414. }
  5415. }
  5416. <?php
  5417. namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
  5418. /**
  5419. * @deprecated Use {@see SplDoublyLinkedListFilter} instead.
  5420. */
  5421. class SplDoublyLinkedList extends SplDoublyLinkedListFilter
  5422. {
  5423. }
  5424. <?php
  5425. namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
  5426. use Closure;
  5427. use PHPUnitPHAR\DeepCopy\DeepCopy;
  5428. use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
  5429. use SplDoublyLinkedList;
  5430. /**
  5431. * @final
  5432. */
  5433. class SplDoublyLinkedListFilter implements TypeFilter
  5434. {
  5435. private $copier;
  5436. public function __construct(DeepCopy $copier)
  5437. {
  5438. $this->copier = $copier;
  5439. }
  5440. /**
  5441. * {@inheritdoc}
  5442. */
  5443. public function apply($element)
  5444. {
  5445. $newElement = clone $element;
  5446. $copy = $this->createCopyClosure();
  5447. return $copy($newElement);
  5448. }
  5449. private function createCopyClosure()
  5450. {
  5451. $copier = $this->copier;
  5452. $copy = function (SplDoublyLinkedList $list) use ($copier) {
  5453. // Replace each element in the list with a deep copy of itself
  5454. for ($i = 1; $i <= $list->count(); $i++) {
  5455. $copy = $copier->recursiveCopy($list->shift());
  5456. $list->push($copy);
  5457. }
  5458. return $list;
  5459. };
  5460. return Closure::bind($copy, null, DeepCopy::class);
  5461. }
  5462. }
  5463. <?php
  5464. namespace PHPUnitPHAR\DeepCopy\TypeFilter;
  5465. interface TypeFilter
  5466. {
  5467. /**
  5468. * Applies the filter to the object.
  5469. *
  5470. * @param mixed $element
  5471. */
  5472. public function apply($element);
  5473. }
  5474. <?php
  5475. namespace PHPUnitPHAR\DeepCopy\TypeMatcher;
  5476. class TypeMatcher
  5477. {
  5478. /**
  5479. * @var string
  5480. */
  5481. private $type;
  5482. /**
  5483. * @param string $type
  5484. */
  5485. public function __construct($type)
  5486. {
  5487. $this->type = $type;
  5488. }
  5489. /**
  5490. * @param mixed $element
  5491. *
  5492. * @return boolean
  5493. */
  5494. public function matches($element)
  5495. {
  5496. return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type;
  5497. }
  5498. }
  5499. <?php
  5500. namespace PHPUnitPHAR\DeepCopy;
  5501. use function function_exists;
  5502. if (\false === function_exists('PHPUnitPHAR\DeepCopy\deep_copy')) {
  5503. /**
  5504. * Deep copies the given value.
  5505. *
  5506. * @param mixed $value
  5507. * @param bool $useCloneMethod
  5508. *
  5509. * @return mixed
  5510. */
  5511. function deep_copy($value, $useCloneMethod = \false)
  5512. {
  5513. return (new DeepCopy($useCloneMethod))->copy($value);
  5514. }
  5515. }
  5516. The MIT License (MIT)
  5517. Copyright (c) 2013 My C-Sense
  5518. Permission is hereby granted, free of charge, to any person obtaining a copy of
  5519. this software and associated documentation files (the "Software"), to deal in
  5520. the Software without restriction, including without limitation the rights to
  5521. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  5522. the Software, and to permit persons to whom the Software is furnished to do so,
  5523. subject to the following conditions:
  5524. The above copyright notice and this permission notice shall be included in all
  5525. copies or substantial portions of the Software.
  5526. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  5527. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  5528. FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  5529. COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  5530. IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  5531. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  5532. BSD 3-Clause License
  5533. Copyright (c) 2011, Nikita Popov
  5534. All rights reserved.
  5535. Redistribution and use in source and binary forms, with or without
  5536. modification, are permitted provided that the following conditions are met:
  5537. 1. Redistributions of source code must retain the above copyright notice, this
  5538. list of conditions and the following disclaimer.
  5539. 2. Redistributions in binary form must reproduce the above copyright notice,
  5540. this list of conditions and the following disclaimer in the documentation
  5541. and/or other materials provided with the distribution.
  5542. 3. Neither the name of the copyright holder nor the names of its
  5543. contributors may be used to endorse or promote products derived from
  5544. this software without specific prior written permission.
  5545. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  5546. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  5547. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  5548. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  5549. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  5550. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  5551. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  5552. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  5553. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  5554. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5555. <?php
  5556. declare (strict_types=1);
  5557. namespace PHPUnitPHAR\PhpParser;
  5558. interface Builder
  5559. {
  5560. /**
  5561. * Returns the built node.
  5562. *
  5563. * @return Node The built node
  5564. */
  5565. public function getNode(): Node;
  5566. }
  5567. <?php
  5568. declare (strict_types=1);
  5569. namespace PHPUnitPHAR\PhpParser\Builder;
  5570. use PHPUnitPHAR\PhpParser;
  5571. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  5572. use PHPUnitPHAR\PhpParser\Modifiers;
  5573. use PHPUnitPHAR\PhpParser\Node;
  5574. use PHPUnitPHAR\PhpParser\Node\Const_;
  5575. use PHPUnitPHAR\PhpParser\Node\Identifier;
  5576. use PHPUnitPHAR\PhpParser\Node\Stmt;
  5577. class ClassConst implements PhpParser\Builder
  5578. {
  5579. protected int $flags = 0;
  5580. /** @var array<string, mixed> */
  5581. protected array $attributes = [];
  5582. /** @var list<Const_> */
  5583. protected array $constants = [];
  5584. /** @var list<Node\AttributeGroup> */
  5585. protected array $attributeGroups = [];
  5586. /** @var Identifier|Node\Name|Node\ComplexType|null */
  5587. protected ?Node $type = null;
  5588. /**
  5589. * Creates a class constant builder
  5590. *
  5591. * @param string|Identifier $name Name
  5592. * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
  5593. */
  5594. public function __construct($name, $value)
  5595. {
  5596. $this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))];
  5597. }
  5598. /**
  5599. * Add another constant to const group
  5600. *
  5601. * @param string|Identifier $name Name
  5602. * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
  5603. *
  5604. * @return $this The builder instance (for fluid interface)
  5605. */
  5606. public function addConst($name, $value)
  5607. {
  5608. $this->constants[] = new Const_($name, BuilderHelpers::normalizeValue($value));
  5609. return $this;
  5610. }
  5611. /**
  5612. * Makes the constant public.
  5613. *
  5614. * @return $this The builder instance (for fluid interface)
  5615. */
  5616. public function makePublic()
  5617. {
  5618. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
  5619. return $this;
  5620. }
  5621. /**
  5622. * Makes the constant protected.
  5623. *
  5624. * @return $this The builder instance (for fluid interface)
  5625. */
  5626. public function makeProtected()
  5627. {
  5628. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
  5629. return $this;
  5630. }
  5631. /**
  5632. * Makes the constant private.
  5633. *
  5634. * @return $this The builder instance (for fluid interface)
  5635. */
  5636. public function makePrivate()
  5637. {
  5638. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
  5639. return $this;
  5640. }
  5641. /**
  5642. * Makes the constant final.
  5643. *
  5644. * @return $this The builder instance (for fluid interface)
  5645. */
  5646. public function makeFinal()
  5647. {
  5648. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
  5649. return $this;
  5650. }
  5651. /**
  5652. * Sets doc comment for the constant.
  5653. *
  5654. * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
  5655. *
  5656. * @return $this The builder instance (for fluid interface)
  5657. */
  5658. public function setDocComment($docComment)
  5659. {
  5660. $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
  5661. return $this;
  5662. }
  5663. /**
  5664. * Adds an attribute group.
  5665. *
  5666. * @param Node\Attribute|Node\AttributeGroup $attribute
  5667. *
  5668. * @return $this The builder instance (for fluid interface)
  5669. */
  5670. public function addAttribute($attribute)
  5671. {
  5672. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  5673. return $this;
  5674. }
  5675. /**
  5676. * Sets the constant type.
  5677. *
  5678. * @param string|Node\Name|Identifier|Node\ComplexType $type
  5679. *
  5680. * @return $this
  5681. */
  5682. public function setType($type)
  5683. {
  5684. $this->type = BuilderHelpers::normalizeType($type);
  5685. return $this;
  5686. }
  5687. /**
  5688. * Returns the built class node.
  5689. *
  5690. * @return Stmt\ClassConst The built constant node
  5691. */
  5692. public function getNode(): PhpParser\Node
  5693. {
  5694. return new Stmt\ClassConst($this->constants, $this->flags, $this->attributes, $this->attributeGroups, $this->type);
  5695. }
  5696. }
  5697. <?php
  5698. declare (strict_types=1);
  5699. namespace PHPUnitPHAR\PhpParser\Builder;
  5700. use PHPUnitPHAR\PhpParser;
  5701. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  5702. use PHPUnitPHAR\PhpParser\Modifiers;
  5703. use PHPUnitPHAR\PhpParser\Node;
  5704. use PHPUnitPHAR\PhpParser\Node\Name;
  5705. use PHPUnitPHAR\PhpParser\Node\Stmt;
  5706. class Class_ extends Declaration
  5707. {
  5708. protected string $name;
  5709. protected ?Name $extends = null;
  5710. /** @var list<Name> */
  5711. protected array $implements = [];
  5712. protected int $flags = 0;
  5713. /** @var list<Stmt\TraitUse> */
  5714. protected array $uses = [];
  5715. /** @var list<Stmt\ClassConst> */
  5716. protected array $constants = [];
  5717. /** @var list<Stmt\Property> */
  5718. protected array $properties = [];
  5719. /** @var list<Stmt\ClassMethod> */
  5720. protected array $methods = [];
  5721. /** @var list<Node\AttributeGroup> */
  5722. protected array $attributeGroups = [];
  5723. /**
  5724. * Creates a class builder.
  5725. *
  5726. * @param string $name Name of the class
  5727. */
  5728. public function __construct(string $name)
  5729. {
  5730. $this->name = $name;
  5731. }
  5732. /**
  5733. * Extends a class.
  5734. *
  5735. * @param Name|string $class Name of class to extend
  5736. *
  5737. * @return $this The builder instance (for fluid interface)
  5738. */
  5739. public function extend($class)
  5740. {
  5741. $this->extends = BuilderHelpers::normalizeName($class);
  5742. return $this;
  5743. }
  5744. /**
  5745. * Implements one or more interfaces.
  5746. *
  5747. * @param Name|string ...$interfaces Names of interfaces to implement
  5748. *
  5749. * @return $this The builder instance (for fluid interface)
  5750. */
  5751. public function implement(...$interfaces)
  5752. {
  5753. foreach ($interfaces as $interface) {
  5754. $this->implements[] = BuilderHelpers::normalizeName($interface);
  5755. }
  5756. return $this;
  5757. }
  5758. /**
  5759. * Makes the class abstract.
  5760. *
  5761. * @return $this The builder instance (for fluid interface)
  5762. */
  5763. public function makeAbstract()
  5764. {
  5765. $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::ABSTRACT);
  5766. return $this;
  5767. }
  5768. /**
  5769. * Makes the class final.
  5770. *
  5771. * @return $this The builder instance (for fluid interface)
  5772. */
  5773. public function makeFinal()
  5774. {
  5775. $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::FINAL);
  5776. return $this;
  5777. }
  5778. /**
  5779. * Makes the class readonly.
  5780. *
  5781. * @return $this The builder instance (for fluid interface)
  5782. */
  5783. public function makeReadonly()
  5784. {
  5785. $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::READONLY);
  5786. return $this;
  5787. }
  5788. /**
  5789. * Adds a statement.
  5790. *
  5791. * @param Stmt|PhpParser\Builder $stmt The statement to add
  5792. *
  5793. * @return $this The builder instance (for fluid interface)
  5794. */
  5795. public function addStmt($stmt)
  5796. {
  5797. $stmt = BuilderHelpers::normalizeNode($stmt);
  5798. if ($stmt instanceof Stmt\Property) {
  5799. $this->properties[] = $stmt;
  5800. } elseif ($stmt instanceof Stmt\ClassMethod) {
  5801. $this->methods[] = $stmt;
  5802. } elseif ($stmt instanceof Stmt\TraitUse) {
  5803. $this->uses[] = $stmt;
  5804. } elseif ($stmt instanceof Stmt\ClassConst) {
  5805. $this->constants[] = $stmt;
  5806. } else {
  5807. throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
  5808. }
  5809. return $this;
  5810. }
  5811. /**
  5812. * Adds an attribute group.
  5813. *
  5814. * @param Node\Attribute|Node\AttributeGroup $attribute
  5815. *
  5816. * @return $this The builder instance (for fluid interface)
  5817. */
  5818. public function addAttribute($attribute)
  5819. {
  5820. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  5821. return $this;
  5822. }
  5823. /**
  5824. * Returns the built class node.
  5825. *
  5826. * @return Stmt\Class_ The built class node
  5827. */
  5828. public function getNode(): PhpParser\Node
  5829. {
  5830. return new Stmt\Class_($this->name, ['flags' => $this->flags, 'extends' => $this->extends, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
  5831. }
  5832. }
  5833. <?php
  5834. declare (strict_types=1);
  5835. namespace PHPUnitPHAR\PhpParser\Builder;
  5836. use PHPUnitPHAR\PhpParser;
  5837. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  5838. abstract class Declaration implements PhpParser\Builder
  5839. {
  5840. /** @var array<string, mixed> */
  5841. protected array $attributes = [];
  5842. /**
  5843. * Adds a statement.
  5844. *
  5845. * @param PhpParser\Node\Stmt|PhpParser\Builder $stmt The statement to add
  5846. *
  5847. * @return $this The builder instance (for fluid interface)
  5848. */
  5849. abstract public function addStmt($stmt);
  5850. /**
  5851. * Adds multiple statements.
  5852. *
  5853. * @param (PhpParser\Node\Stmt|PhpParser\Builder)[] $stmts The statements to add
  5854. *
  5855. * @return $this The builder instance (for fluid interface)
  5856. */
  5857. public function addStmts(array $stmts)
  5858. {
  5859. foreach ($stmts as $stmt) {
  5860. $this->addStmt($stmt);
  5861. }
  5862. return $this;
  5863. }
  5864. /**
  5865. * Sets doc comment for the declaration.
  5866. *
  5867. * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
  5868. *
  5869. * @return $this The builder instance (for fluid interface)
  5870. */
  5871. public function setDocComment($docComment)
  5872. {
  5873. $this->attributes['comments'] = [BuilderHelpers::normalizeDocComment($docComment)];
  5874. return $this;
  5875. }
  5876. }
  5877. <?php
  5878. declare (strict_types=1);
  5879. namespace PHPUnitPHAR\PhpParser\Builder;
  5880. use PHPUnitPHAR\PhpParser;
  5881. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  5882. use PHPUnitPHAR\PhpParser\Node;
  5883. use PHPUnitPHAR\PhpParser\Node\Identifier;
  5884. use PHPUnitPHAR\PhpParser\Node\Stmt;
  5885. class EnumCase implements PhpParser\Builder
  5886. {
  5887. /** @var Identifier|string */
  5888. protected $name;
  5889. protected ?Node\Expr $value = null;
  5890. /** @var array<string, mixed> */
  5891. protected array $attributes = [];
  5892. /** @var list<Node\AttributeGroup> */
  5893. protected array $attributeGroups = [];
  5894. /**
  5895. * Creates an enum case builder.
  5896. *
  5897. * @param string|Identifier $name Name
  5898. */
  5899. public function __construct($name)
  5900. {
  5901. $this->name = $name;
  5902. }
  5903. /**
  5904. * Sets the value.
  5905. *
  5906. * @param Node\Expr|string|int $value
  5907. *
  5908. * @return $this
  5909. */
  5910. public function setValue($value)
  5911. {
  5912. $this->value = BuilderHelpers::normalizeValue($value);
  5913. return $this;
  5914. }
  5915. /**
  5916. * Sets doc comment for the constant.
  5917. *
  5918. * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
  5919. *
  5920. * @return $this The builder instance (for fluid interface)
  5921. */
  5922. public function setDocComment($docComment)
  5923. {
  5924. $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
  5925. return $this;
  5926. }
  5927. /**
  5928. * Adds an attribute group.
  5929. *
  5930. * @param Node\Attribute|Node\AttributeGroup $attribute
  5931. *
  5932. * @return $this The builder instance (for fluid interface)
  5933. */
  5934. public function addAttribute($attribute)
  5935. {
  5936. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  5937. return $this;
  5938. }
  5939. /**
  5940. * Returns the built enum case node.
  5941. *
  5942. * @return Stmt\EnumCase The built constant node
  5943. */
  5944. public function getNode(): PhpParser\Node
  5945. {
  5946. return new Stmt\EnumCase($this->name, $this->value, $this->attributeGroups, $this->attributes);
  5947. }
  5948. }
  5949. <?php
  5950. declare (strict_types=1);
  5951. namespace PHPUnitPHAR\PhpParser\Builder;
  5952. use PHPUnitPHAR\PhpParser;
  5953. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  5954. use PHPUnitPHAR\PhpParser\Node;
  5955. use PHPUnitPHAR\PhpParser\Node\Identifier;
  5956. use PHPUnitPHAR\PhpParser\Node\Name;
  5957. use PHPUnitPHAR\PhpParser\Node\Stmt;
  5958. class Enum_ extends Declaration
  5959. {
  5960. protected string $name;
  5961. protected ?Identifier $scalarType = null;
  5962. /** @var list<Name> */
  5963. protected array $implements = [];
  5964. /** @var list<Stmt\TraitUse> */
  5965. protected array $uses = [];
  5966. /** @var list<Stmt\EnumCase> */
  5967. protected array $enumCases = [];
  5968. /** @var list<Stmt\ClassConst> */
  5969. protected array $constants = [];
  5970. /** @var list<Stmt\ClassMethod> */
  5971. protected array $methods = [];
  5972. /** @var list<Node\AttributeGroup> */
  5973. protected array $attributeGroups = [];
  5974. /**
  5975. * Creates an enum builder.
  5976. *
  5977. * @param string $name Name of the enum
  5978. */
  5979. public function __construct(string $name)
  5980. {
  5981. $this->name = $name;
  5982. }
  5983. /**
  5984. * Sets the scalar type.
  5985. *
  5986. * @param string|Identifier $scalarType
  5987. *
  5988. * @return $this
  5989. */
  5990. public function setScalarType($scalarType)
  5991. {
  5992. $this->scalarType = BuilderHelpers::normalizeType($scalarType);
  5993. return $this;
  5994. }
  5995. /**
  5996. * Implements one or more interfaces.
  5997. *
  5998. * @param Name|string ...$interfaces Names of interfaces to implement
  5999. *
  6000. * @return $this The builder instance (for fluid interface)
  6001. */
  6002. public function implement(...$interfaces)
  6003. {
  6004. foreach ($interfaces as $interface) {
  6005. $this->implements[] = BuilderHelpers::normalizeName($interface);
  6006. }
  6007. return $this;
  6008. }
  6009. /**
  6010. * Adds a statement.
  6011. *
  6012. * @param Stmt|PhpParser\Builder $stmt The statement to add
  6013. *
  6014. * @return $this The builder instance (for fluid interface)
  6015. */
  6016. public function addStmt($stmt)
  6017. {
  6018. $stmt = BuilderHelpers::normalizeNode($stmt);
  6019. if ($stmt instanceof Stmt\EnumCase) {
  6020. $this->enumCases[] = $stmt;
  6021. } elseif ($stmt instanceof Stmt\ClassMethod) {
  6022. $this->methods[] = $stmt;
  6023. } elseif ($stmt instanceof Stmt\TraitUse) {
  6024. $this->uses[] = $stmt;
  6025. } elseif ($stmt instanceof Stmt\ClassConst) {
  6026. $this->constants[] = $stmt;
  6027. } else {
  6028. throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
  6029. }
  6030. return $this;
  6031. }
  6032. /**
  6033. * Adds an attribute group.
  6034. *
  6035. * @param Node\Attribute|Node\AttributeGroup $attribute
  6036. *
  6037. * @return $this The builder instance (for fluid interface)
  6038. */
  6039. public function addAttribute($attribute)
  6040. {
  6041. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6042. return $this;
  6043. }
  6044. /**
  6045. * Returns the built class node.
  6046. *
  6047. * @return Stmt\Enum_ The built enum node
  6048. */
  6049. public function getNode(): PhpParser\Node
  6050. {
  6051. return new Stmt\Enum_($this->name, ['scalarType' => $this->scalarType, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->enumCases, $this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
  6052. }
  6053. }
  6054. <?php
  6055. declare (strict_types=1);
  6056. namespace PHPUnitPHAR\PhpParser\Builder;
  6057. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6058. use PHPUnitPHAR\PhpParser\Node;
  6059. abstract class FunctionLike extends Declaration
  6060. {
  6061. protected bool $returnByRef = \false;
  6062. /** @var Node\Param[] */
  6063. protected array $params = [];
  6064. /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
  6065. protected ?Node $returnType = null;
  6066. /**
  6067. * Make the function return by reference.
  6068. *
  6069. * @return $this The builder instance (for fluid interface)
  6070. */
  6071. public function makeReturnByRef()
  6072. {
  6073. $this->returnByRef = \true;
  6074. return $this;
  6075. }
  6076. /**
  6077. * Adds a parameter.
  6078. *
  6079. * @param Node\Param|Param $param The parameter to add
  6080. *
  6081. * @return $this The builder instance (for fluid interface)
  6082. */
  6083. public function addParam($param)
  6084. {
  6085. $param = BuilderHelpers::normalizeNode($param);
  6086. if (!$param instanceof Node\Param) {
  6087. throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType()));
  6088. }
  6089. $this->params[] = $param;
  6090. return $this;
  6091. }
  6092. /**
  6093. * Adds multiple parameters.
  6094. *
  6095. * @param (Node\Param|Param)[] $params The parameters to add
  6096. *
  6097. * @return $this The builder instance (for fluid interface)
  6098. */
  6099. public function addParams(array $params)
  6100. {
  6101. foreach ($params as $param) {
  6102. $this->addParam($param);
  6103. }
  6104. return $this;
  6105. }
  6106. /**
  6107. * Sets the return type for PHP 7.
  6108. *
  6109. * @param string|Node\Name|Node\Identifier|Node\ComplexType $type
  6110. *
  6111. * @return $this The builder instance (for fluid interface)
  6112. */
  6113. public function setReturnType($type)
  6114. {
  6115. $this->returnType = BuilderHelpers::normalizeType($type);
  6116. return $this;
  6117. }
  6118. }
  6119. <?php
  6120. declare (strict_types=1);
  6121. namespace PHPUnitPHAR\PhpParser\Builder;
  6122. use PHPUnitPHAR\PhpParser;
  6123. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6124. use PHPUnitPHAR\PhpParser\Node;
  6125. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6126. class Function_ extends FunctionLike
  6127. {
  6128. protected string $name;
  6129. /** @var list<Stmt> */
  6130. protected array $stmts = [];
  6131. /** @var list<Node\AttributeGroup> */
  6132. protected array $attributeGroups = [];
  6133. /**
  6134. * Creates a function builder.
  6135. *
  6136. * @param string $name Name of the function
  6137. */
  6138. public function __construct(string $name)
  6139. {
  6140. $this->name = $name;
  6141. }
  6142. /**
  6143. * Adds a statement.
  6144. *
  6145. * @param Node|PhpParser\Builder $stmt The statement to add
  6146. *
  6147. * @return $this The builder instance (for fluid interface)
  6148. */
  6149. public function addStmt($stmt)
  6150. {
  6151. $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
  6152. return $this;
  6153. }
  6154. /**
  6155. * Adds an attribute group.
  6156. *
  6157. * @param Node\Attribute|Node\AttributeGroup $attribute
  6158. *
  6159. * @return $this The builder instance (for fluid interface)
  6160. */
  6161. public function addAttribute($attribute)
  6162. {
  6163. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6164. return $this;
  6165. }
  6166. /**
  6167. * Returns the built function node.
  6168. *
  6169. * @return Stmt\Function_ The built function node
  6170. */
  6171. public function getNode(): Node
  6172. {
  6173. return new Stmt\Function_($this->name, ['byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
  6174. }
  6175. }
  6176. <?php
  6177. declare (strict_types=1);
  6178. namespace PHPUnitPHAR\PhpParser\Builder;
  6179. use PHPUnitPHAR\PhpParser;
  6180. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6181. use PHPUnitPHAR\PhpParser\Node;
  6182. use PHPUnitPHAR\PhpParser\Node\Name;
  6183. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6184. class Interface_ extends Declaration
  6185. {
  6186. protected string $name;
  6187. /** @var list<Name> */
  6188. protected array $extends = [];
  6189. /** @var list<Stmt\ClassConst> */
  6190. protected array $constants = [];
  6191. /** @var list<Stmt\ClassMethod> */
  6192. protected array $methods = [];
  6193. /** @var list<Node\AttributeGroup> */
  6194. protected array $attributeGroups = [];
  6195. /**
  6196. * Creates an interface builder.
  6197. *
  6198. * @param string $name Name of the interface
  6199. */
  6200. public function __construct(string $name)
  6201. {
  6202. $this->name = $name;
  6203. }
  6204. /**
  6205. * Extends one or more interfaces.
  6206. *
  6207. * @param Name|string ...$interfaces Names of interfaces to extend
  6208. *
  6209. * @return $this The builder instance (for fluid interface)
  6210. */
  6211. public function extend(...$interfaces)
  6212. {
  6213. foreach ($interfaces as $interface) {
  6214. $this->extends[] = BuilderHelpers::normalizeName($interface);
  6215. }
  6216. return $this;
  6217. }
  6218. /**
  6219. * Adds a statement.
  6220. *
  6221. * @param Stmt|PhpParser\Builder $stmt The statement to add
  6222. *
  6223. * @return $this The builder instance (for fluid interface)
  6224. */
  6225. public function addStmt($stmt)
  6226. {
  6227. $stmt = BuilderHelpers::normalizeNode($stmt);
  6228. if ($stmt instanceof Stmt\ClassConst) {
  6229. $this->constants[] = $stmt;
  6230. } elseif ($stmt instanceof Stmt\ClassMethod) {
  6231. // we erase all statements in the body of an interface method
  6232. $stmt->stmts = null;
  6233. $this->methods[] = $stmt;
  6234. } else {
  6235. throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
  6236. }
  6237. return $this;
  6238. }
  6239. /**
  6240. * Adds an attribute group.
  6241. *
  6242. * @param Node\Attribute|Node\AttributeGroup $attribute
  6243. *
  6244. * @return $this The builder instance (for fluid interface)
  6245. */
  6246. public function addAttribute($attribute)
  6247. {
  6248. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6249. return $this;
  6250. }
  6251. /**
  6252. * Returns the built interface node.
  6253. *
  6254. * @return Stmt\Interface_ The built interface node
  6255. */
  6256. public function getNode(): PhpParser\Node
  6257. {
  6258. return new Stmt\Interface_($this->name, ['extends' => $this->extends, 'stmts' => array_merge($this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
  6259. }
  6260. }
  6261. <?php
  6262. declare (strict_types=1);
  6263. namespace PHPUnitPHAR\PhpParser\Builder;
  6264. use PHPUnitPHAR\PhpParser;
  6265. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6266. use PHPUnitPHAR\PhpParser\Modifiers;
  6267. use PHPUnitPHAR\PhpParser\Node;
  6268. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6269. class Method extends FunctionLike
  6270. {
  6271. protected string $name;
  6272. protected int $flags = 0;
  6273. /** @var list<Stmt>|null */
  6274. protected ?array $stmts = [];
  6275. /** @var list<Node\AttributeGroup> */
  6276. protected array $attributeGroups = [];
  6277. /**
  6278. * Creates a method builder.
  6279. *
  6280. * @param string $name Name of the method
  6281. */
  6282. public function __construct(string $name)
  6283. {
  6284. $this->name = $name;
  6285. }
  6286. /**
  6287. * Makes the method public.
  6288. *
  6289. * @return $this The builder instance (for fluid interface)
  6290. */
  6291. public function makePublic()
  6292. {
  6293. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
  6294. return $this;
  6295. }
  6296. /**
  6297. * Makes the method protected.
  6298. *
  6299. * @return $this The builder instance (for fluid interface)
  6300. */
  6301. public function makeProtected()
  6302. {
  6303. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
  6304. return $this;
  6305. }
  6306. /**
  6307. * Makes the method private.
  6308. *
  6309. * @return $this The builder instance (for fluid interface)
  6310. */
  6311. public function makePrivate()
  6312. {
  6313. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
  6314. return $this;
  6315. }
  6316. /**
  6317. * Makes the method static.
  6318. *
  6319. * @return $this The builder instance (for fluid interface)
  6320. */
  6321. public function makeStatic()
  6322. {
  6323. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
  6324. return $this;
  6325. }
  6326. /**
  6327. * Makes the method abstract.
  6328. *
  6329. * @return $this The builder instance (for fluid interface)
  6330. */
  6331. public function makeAbstract()
  6332. {
  6333. if (!empty($this->stmts)) {
  6334. throw new \LogicException('Cannot make method with statements abstract');
  6335. }
  6336. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
  6337. $this->stmts = null;
  6338. // abstract methods don't have statements
  6339. return $this;
  6340. }
  6341. /**
  6342. * Makes the method final.
  6343. *
  6344. * @return $this The builder instance (for fluid interface)
  6345. */
  6346. public function makeFinal()
  6347. {
  6348. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
  6349. return $this;
  6350. }
  6351. /**
  6352. * Adds a statement.
  6353. *
  6354. * @param Node|PhpParser\Builder $stmt The statement to add
  6355. *
  6356. * @return $this The builder instance (for fluid interface)
  6357. */
  6358. public function addStmt($stmt)
  6359. {
  6360. if (null === $this->stmts) {
  6361. throw new \LogicException('Cannot add statements to an abstract method');
  6362. }
  6363. $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
  6364. return $this;
  6365. }
  6366. /**
  6367. * Adds an attribute group.
  6368. *
  6369. * @param Node\Attribute|Node\AttributeGroup $attribute
  6370. *
  6371. * @return $this The builder instance (for fluid interface)
  6372. */
  6373. public function addAttribute($attribute)
  6374. {
  6375. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6376. return $this;
  6377. }
  6378. /**
  6379. * Returns the built method node.
  6380. *
  6381. * @return Stmt\ClassMethod The built method node
  6382. */
  6383. public function getNode(): Node
  6384. {
  6385. return new Stmt\ClassMethod($this->name, ['flags' => $this->flags, 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
  6386. }
  6387. }
  6388. <?php
  6389. declare (strict_types=1);
  6390. namespace PHPUnitPHAR\PhpParser\Builder;
  6391. use PHPUnitPHAR\PhpParser;
  6392. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6393. use PHPUnitPHAR\PhpParser\Node;
  6394. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6395. class Namespace_ extends Declaration
  6396. {
  6397. private ?Node\Name $name;
  6398. /** @var Stmt[] */
  6399. private array $stmts = [];
  6400. /**
  6401. * Creates a namespace builder.
  6402. *
  6403. * @param Node\Name|string|null $name Name of the namespace
  6404. */
  6405. public function __construct($name)
  6406. {
  6407. $this->name = null !== $name ? BuilderHelpers::normalizeName($name) : null;
  6408. }
  6409. /**
  6410. * Adds a statement.
  6411. *
  6412. * @param Node|PhpParser\Builder $stmt The statement to add
  6413. *
  6414. * @return $this The builder instance (for fluid interface)
  6415. */
  6416. public function addStmt($stmt)
  6417. {
  6418. $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
  6419. return $this;
  6420. }
  6421. /**
  6422. * Returns the built node.
  6423. *
  6424. * @return Stmt\Namespace_ The built node
  6425. */
  6426. public function getNode(): Node
  6427. {
  6428. return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
  6429. }
  6430. }
  6431. <?php
  6432. declare (strict_types=1);
  6433. namespace PHPUnitPHAR\PhpParser\Builder;
  6434. use PHPUnitPHAR\PhpParser;
  6435. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6436. use PHPUnitPHAR\PhpParser\Modifiers;
  6437. use PHPUnitPHAR\PhpParser\Node;
  6438. class Param implements PhpParser\Builder
  6439. {
  6440. protected string $name;
  6441. protected ?Node\Expr $default = null;
  6442. /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
  6443. protected ?Node $type = null;
  6444. protected bool $byRef = \false;
  6445. protected int $flags = 0;
  6446. protected bool $variadic = \false;
  6447. /** @var list<Node\AttributeGroup> */
  6448. protected array $attributeGroups = [];
  6449. /**
  6450. * Creates a parameter builder.
  6451. *
  6452. * @param string $name Name of the parameter
  6453. */
  6454. public function __construct(string $name)
  6455. {
  6456. $this->name = $name;
  6457. }
  6458. /**
  6459. * Sets default value for the parameter.
  6460. *
  6461. * @param mixed $value Default value to use
  6462. *
  6463. * @return $this The builder instance (for fluid interface)
  6464. */
  6465. public function setDefault($value)
  6466. {
  6467. $this->default = BuilderHelpers::normalizeValue($value);
  6468. return $this;
  6469. }
  6470. /**
  6471. * Sets type for the parameter.
  6472. *
  6473. * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type
  6474. *
  6475. * @return $this The builder instance (for fluid interface)
  6476. */
  6477. public function setType($type)
  6478. {
  6479. $this->type = BuilderHelpers::normalizeType($type);
  6480. if ($this->type == 'void') {
  6481. throw new \LogicException('Parameter type cannot be void');
  6482. }
  6483. return $this;
  6484. }
  6485. /**
  6486. * Make the parameter accept the value by reference.
  6487. *
  6488. * @return $this The builder instance (for fluid interface)
  6489. */
  6490. public function makeByRef()
  6491. {
  6492. $this->byRef = \true;
  6493. return $this;
  6494. }
  6495. /**
  6496. * Make the parameter variadic
  6497. *
  6498. * @return $this The builder instance (for fluid interface)
  6499. */
  6500. public function makeVariadic()
  6501. {
  6502. $this->variadic = \true;
  6503. return $this;
  6504. }
  6505. /**
  6506. * Makes the (promoted) parameter public.
  6507. *
  6508. * @return $this The builder instance (for fluid interface)
  6509. */
  6510. public function makePublic()
  6511. {
  6512. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
  6513. return $this;
  6514. }
  6515. /**
  6516. * Makes the (promoted) parameter protected.
  6517. *
  6518. * @return $this The builder instance (for fluid interface)
  6519. */
  6520. public function makeProtected()
  6521. {
  6522. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
  6523. return $this;
  6524. }
  6525. /**
  6526. * Makes the (promoted) parameter private.
  6527. *
  6528. * @return $this The builder instance (for fluid interface)
  6529. */
  6530. public function makePrivate()
  6531. {
  6532. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
  6533. return $this;
  6534. }
  6535. /**
  6536. * Makes the (promoted) parameter readonly.
  6537. *
  6538. * @return $this The builder instance (for fluid interface)
  6539. */
  6540. public function makeReadonly()
  6541. {
  6542. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
  6543. return $this;
  6544. }
  6545. /**
  6546. * Gives the promoted property private(set) visibility.
  6547. *
  6548. * @return $this The builder instance (for fluid interface)
  6549. */
  6550. public function makePrivateSet()
  6551. {
  6552. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
  6553. return $this;
  6554. }
  6555. /**
  6556. * Gives the promoted property protected(set) visibility.
  6557. *
  6558. * @return $this The builder instance (for fluid interface)
  6559. */
  6560. public function makeProtectedSet()
  6561. {
  6562. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
  6563. return $this;
  6564. }
  6565. /**
  6566. * Adds an attribute group.
  6567. *
  6568. * @param Node\Attribute|Node\AttributeGroup $attribute
  6569. *
  6570. * @return $this The builder instance (for fluid interface)
  6571. */
  6572. public function addAttribute($attribute)
  6573. {
  6574. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6575. return $this;
  6576. }
  6577. /**
  6578. * Returns the built parameter node.
  6579. *
  6580. * @return Node\Param The built parameter node
  6581. */
  6582. public function getNode(): Node
  6583. {
  6584. return new Node\Param(new Node\Expr\Variable($this->name), $this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups);
  6585. }
  6586. }
  6587. <?php
  6588. declare (strict_types=1);
  6589. namespace PHPUnitPHAR\PhpParser\Builder;
  6590. use PHPUnitPHAR\PhpParser;
  6591. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6592. use PHPUnitPHAR\PhpParser\Modifiers;
  6593. use PHPUnitPHAR\PhpParser\Node;
  6594. use PHPUnitPHAR\PhpParser\Node\Identifier;
  6595. use PHPUnitPHAR\PhpParser\Node\Name;
  6596. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6597. use PHPUnitPHAR\PhpParser\Node\ComplexType;
  6598. class Property implements PhpParser\Builder
  6599. {
  6600. protected string $name;
  6601. protected int $flags = 0;
  6602. protected ?Node\Expr $default = null;
  6603. /** @var array<string, mixed> */
  6604. protected array $attributes = [];
  6605. /** @var null|Identifier|Name|ComplexType */
  6606. protected ?Node $type = null;
  6607. /** @var list<Node\AttributeGroup> */
  6608. protected array $attributeGroups = [];
  6609. /** @var list<Node\PropertyHook> */
  6610. protected array $hooks = [];
  6611. /**
  6612. * Creates a property builder.
  6613. *
  6614. * @param string $name Name of the property
  6615. */
  6616. public function __construct(string $name)
  6617. {
  6618. $this->name = $name;
  6619. }
  6620. /**
  6621. * Makes the property public.
  6622. *
  6623. * @return $this The builder instance (for fluid interface)
  6624. */
  6625. public function makePublic()
  6626. {
  6627. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
  6628. return $this;
  6629. }
  6630. /**
  6631. * Makes the property protected.
  6632. *
  6633. * @return $this The builder instance (for fluid interface)
  6634. */
  6635. public function makeProtected()
  6636. {
  6637. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
  6638. return $this;
  6639. }
  6640. /**
  6641. * Makes the property private.
  6642. *
  6643. * @return $this The builder instance (for fluid interface)
  6644. */
  6645. public function makePrivate()
  6646. {
  6647. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
  6648. return $this;
  6649. }
  6650. /**
  6651. * Makes the property static.
  6652. *
  6653. * @return $this The builder instance (for fluid interface)
  6654. */
  6655. public function makeStatic()
  6656. {
  6657. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
  6658. return $this;
  6659. }
  6660. /**
  6661. * Makes the property readonly.
  6662. *
  6663. * @return $this The builder instance (for fluid interface)
  6664. */
  6665. public function makeReadonly()
  6666. {
  6667. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
  6668. return $this;
  6669. }
  6670. /**
  6671. * Makes the property abstract. Requires at least one property hook to be specified as well.
  6672. *
  6673. * @return $this The builder instance (for fluid interface)
  6674. */
  6675. public function makeAbstract()
  6676. {
  6677. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
  6678. return $this;
  6679. }
  6680. /**
  6681. * Makes the property final.
  6682. *
  6683. * @return $this The builder instance (for fluid interface)
  6684. */
  6685. public function makeFinal()
  6686. {
  6687. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
  6688. return $this;
  6689. }
  6690. /**
  6691. * Gives the property private(set) visibility.
  6692. *
  6693. * @return $this The builder instance (for fluid interface)
  6694. */
  6695. public function makePrivateSet()
  6696. {
  6697. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
  6698. return $this;
  6699. }
  6700. /**
  6701. * Gives the property protected(set) visibility.
  6702. *
  6703. * @return $this The builder instance (for fluid interface)
  6704. */
  6705. public function makeProtectedSet()
  6706. {
  6707. $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
  6708. return $this;
  6709. }
  6710. /**
  6711. * Sets default value for the property.
  6712. *
  6713. * @param mixed $value Default value to use
  6714. *
  6715. * @return $this The builder instance (for fluid interface)
  6716. */
  6717. public function setDefault($value)
  6718. {
  6719. $this->default = BuilderHelpers::normalizeValue($value);
  6720. return $this;
  6721. }
  6722. /**
  6723. * Sets doc comment for the property.
  6724. *
  6725. * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
  6726. *
  6727. * @return $this The builder instance (for fluid interface)
  6728. */
  6729. public function setDocComment($docComment)
  6730. {
  6731. $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
  6732. return $this;
  6733. }
  6734. /**
  6735. * Sets the property type for PHP 7.4+.
  6736. *
  6737. * @param string|Name|Identifier|ComplexType $type
  6738. *
  6739. * @return $this
  6740. */
  6741. public function setType($type)
  6742. {
  6743. $this->type = BuilderHelpers::normalizeType($type);
  6744. return $this;
  6745. }
  6746. /**
  6747. * Adds an attribute group.
  6748. *
  6749. * @param Node\Attribute|Node\AttributeGroup $attribute
  6750. *
  6751. * @return $this The builder instance (for fluid interface)
  6752. */
  6753. public function addAttribute($attribute)
  6754. {
  6755. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  6756. return $this;
  6757. }
  6758. /**
  6759. * Adds a property hook.
  6760. *
  6761. * @return $this The builder instance (for fluid interface)
  6762. */
  6763. public function addHook(Node\PropertyHook $hook)
  6764. {
  6765. $this->hooks[] = $hook;
  6766. return $this;
  6767. }
  6768. /**
  6769. * Returns the built class node.
  6770. *
  6771. * @return Stmt\Property The built property node
  6772. */
  6773. public function getNode(): PhpParser\Node
  6774. {
  6775. if ($this->flags & Modifiers::ABSTRACT && !$this->hooks) {
  6776. throw new PhpParser\Error('Only hooked properties may be declared abstract');
  6777. }
  6778. return new Stmt\Property($this->flags !== 0 ? $this->flags : Modifiers::PUBLIC, [new Node\PropertyItem($this->name, $this->default)], $this->attributes, $this->type, $this->attributeGroups, $this->hooks);
  6779. }
  6780. }
  6781. <?php
  6782. declare (strict_types=1);
  6783. namespace PHPUnitPHAR\PhpParser\Builder;
  6784. use PHPUnitPHAR\PhpParser\Builder;
  6785. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6786. use PHPUnitPHAR\PhpParser\Node;
  6787. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6788. class TraitUse implements Builder
  6789. {
  6790. /** @var Node\Name[] */
  6791. protected array $traits = [];
  6792. /** @var Stmt\TraitUseAdaptation[] */
  6793. protected array $adaptations = [];
  6794. /**
  6795. * Creates a trait use builder.
  6796. *
  6797. * @param Node\Name|string ...$traits Names of used traits
  6798. */
  6799. public function __construct(...$traits)
  6800. {
  6801. foreach ($traits as $trait) {
  6802. $this->and($trait);
  6803. }
  6804. }
  6805. /**
  6806. * Adds used trait.
  6807. *
  6808. * @param Node\Name|string $trait Trait name
  6809. *
  6810. * @return $this The builder instance (for fluid interface)
  6811. */
  6812. public function and($trait)
  6813. {
  6814. $this->traits[] = BuilderHelpers::normalizeName($trait);
  6815. return $this;
  6816. }
  6817. /**
  6818. * Adds trait adaptation.
  6819. *
  6820. * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation
  6821. *
  6822. * @return $this The builder instance (for fluid interface)
  6823. */
  6824. public function with($adaptation)
  6825. {
  6826. $adaptation = BuilderHelpers::normalizeNode($adaptation);
  6827. if (!$adaptation instanceof Stmt\TraitUseAdaptation) {
  6828. throw new \LogicException('Adaptation must have type TraitUseAdaptation');
  6829. }
  6830. $this->adaptations[] = $adaptation;
  6831. return $this;
  6832. }
  6833. /**
  6834. * Returns the built node.
  6835. *
  6836. * @return Node The built node
  6837. */
  6838. public function getNode(): Node
  6839. {
  6840. return new Stmt\TraitUse($this->traits, $this->adaptations);
  6841. }
  6842. }
  6843. <?php
  6844. declare (strict_types=1);
  6845. namespace PHPUnitPHAR\PhpParser\Builder;
  6846. use PHPUnitPHAR\PhpParser\Builder;
  6847. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6848. use PHPUnitPHAR\PhpParser\Modifiers;
  6849. use PHPUnitPHAR\PhpParser\Node;
  6850. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6851. class TraitUseAdaptation implements Builder
  6852. {
  6853. private const TYPE_UNDEFINED = 0;
  6854. private const TYPE_ALIAS = 1;
  6855. private const TYPE_PRECEDENCE = 2;
  6856. protected int $type;
  6857. protected ?Node\Name $trait;
  6858. protected Node\Identifier $method;
  6859. protected ?int $modifier = null;
  6860. protected ?Node\Identifier $alias = null;
  6861. /** @var Node\Name[] */
  6862. protected array $insteadof = [];
  6863. /**
  6864. * Creates a trait use adaptation builder.
  6865. *
  6866. * @param Node\Name|string|null $trait Name of adapted trait
  6867. * @param Node\Identifier|string $method Name of adapted method
  6868. */
  6869. public function __construct($trait, $method)
  6870. {
  6871. $this->type = self::TYPE_UNDEFINED;
  6872. $this->trait = is_null($trait) ? null : BuilderHelpers::normalizeName($trait);
  6873. $this->method = BuilderHelpers::normalizeIdentifier($method);
  6874. }
  6875. /**
  6876. * Sets alias of method.
  6877. *
  6878. * @param Node\Identifier|string $alias Alias for adapted method
  6879. *
  6880. * @return $this The builder instance (for fluid interface)
  6881. */
  6882. public function as($alias)
  6883. {
  6884. if ($this->type === self::TYPE_UNDEFINED) {
  6885. $this->type = self::TYPE_ALIAS;
  6886. }
  6887. if ($this->type !== self::TYPE_ALIAS) {
  6888. throw new \LogicException('Cannot set alias for not alias adaptation buider');
  6889. }
  6890. $this->alias = BuilderHelpers::normalizeIdentifier($alias);
  6891. return $this;
  6892. }
  6893. /**
  6894. * Sets adapted method public.
  6895. *
  6896. * @return $this The builder instance (for fluid interface)
  6897. */
  6898. public function makePublic()
  6899. {
  6900. $this->setModifier(Modifiers::PUBLIC);
  6901. return $this;
  6902. }
  6903. /**
  6904. * Sets adapted method protected.
  6905. *
  6906. * @return $this The builder instance (for fluid interface)
  6907. */
  6908. public function makeProtected()
  6909. {
  6910. $this->setModifier(Modifiers::PROTECTED);
  6911. return $this;
  6912. }
  6913. /**
  6914. * Sets adapted method private.
  6915. *
  6916. * @return $this The builder instance (for fluid interface)
  6917. */
  6918. public function makePrivate()
  6919. {
  6920. $this->setModifier(Modifiers::PRIVATE);
  6921. return $this;
  6922. }
  6923. /**
  6924. * Adds overwritten traits.
  6925. *
  6926. * @param Node\Name|string ...$traits Traits for overwrite
  6927. *
  6928. * @return $this The builder instance (for fluid interface)
  6929. */
  6930. public function insteadof(...$traits)
  6931. {
  6932. if ($this->type === self::TYPE_UNDEFINED) {
  6933. if (is_null($this->trait)) {
  6934. throw new \LogicException('Precedence adaptation must have trait');
  6935. }
  6936. $this->type = self::TYPE_PRECEDENCE;
  6937. }
  6938. if ($this->type !== self::TYPE_PRECEDENCE) {
  6939. throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
  6940. }
  6941. foreach ($traits as $trait) {
  6942. $this->insteadof[] = BuilderHelpers::normalizeName($trait);
  6943. }
  6944. return $this;
  6945. }
  6946. protected function setModifier(int $modifier): void
  6947. {
  6948. if ($this->type === self::TYPE_UNDEFINED) {
  6949. $this->type = self::TYPE_ALIAS;
  6950. }
  6951. if ($this->type !== self::TYPE_ALIAS) {
  6952. throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
  6953. }
  6954. if (is_null($this->modifier)) {
  6955. $this->modifier = $modifier;
  6956. } else {
  6957. throw new \LogicException('Multiple access type modifiers are not allowed');
  6958. }
  6959. }
  6960. /**
  6961. * Returns the built node.
  6962. *
  6963. * @return Node The built node
  6964. */
  6965. public function getNode(): Node
  6966. {
  6967. switch ($this->type) {
  6968. case self::TYPE_ALIAS:
  6969. return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
  6970. case self::TYPE_PRECEDENCE:
  6971. return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
  6972. default:
  6973. throw new \LogicException('Type of adaptation is not defined');
  6974. }
  6975. }
  6976. }
  6977. <?php
  6978. declare (strict_types=1);
  6979. namespace PHPUnitPHAR\PhpParser\Builder;
  6980. use PHPUnitPHAR\PhpParser;
  6981. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  6982. use PHPUnitPHAR\PhpParser\Node;
  6983. use PHPUnitPHAR\PhpParser\Node\Stmt;
  6984. class Trait_ extends Declaration
  6985. {
  6986. protected string $name;
  6987. /** @var list<Stmt\TraitUse> */
  6988. protected array $uses = [];
  6989. /** @var list<Stmt\ClassConst> */
  6990. protected array $constants = [];
  6991. /** @var list<Stmt\Property> */
  6992. protected array $properties = [];
  6993. /** @var list<Stmt\ClassMethod> */
  6994. protected array $methods = [];
  6995. /** @var list<Node\AttributeGroup> */
  6996. protected array $attributeGroups = [];
  6997. /**
  6998. * Creates an interface builder.
  6999. *
  7000. * @param string $name Name of the interface
  7001. */
  7002. public function __construct(string $name)
  7003. {
  7004. $this->name = $name;
  7005. }
  7006. /**
  7007. * Adds a statement.
  7008. *
  7009. * @param Stmt|PhpParser\Builder $stmt The statement to add
  7010. *
  7011. * @return $this The builder instance (for fluid interface)
  7012. */
  7013. public function addStmt($stmt)
  7014. {
  7015. $stmt = BuilderHelpers::normalizeNode($stmt);
  7016. if ($stmt instanceof Stmt\Property) {
  7017. $this->properties[] = $stmt;
  7018. } elseif ($stmt instanceof Stmt\ClassMethod) {
  7019. $this->methods[] = $stmt;
  7020. } elseif ($stmt instanceof Stmt\TraitUse) {
  7021. $this->uses[] = $stmt;
  7022. } elseif ($stmt instanceof Stmt\ClassConst) {
  7023. $this->constants[] = $stmt;
  7024. } else {
  7025. throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
  7026. }
  7027. return $this;
  7028. }
  7029. /**
  7030. * Adds an attribute group.
  7031. *
  7032. * @param Node\Attribute|Node\AttributeGroup $attribute
  7033. *
  7034. * @return $this The builder instance (for fluid interface)
  7035. */
  7036. public function addAttribute($attribute)
  7037. {
  7038. $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
  7039. return $this;
  7040. }
  7041. /**
  7042. * Returns the built trait node.
  7043. *
  7044. * @return Stmt\Trait_ The built interface node
  7045. */
  7046. public function getNode(): PhpParser\Node
  7047. {
  7048. return new Stmt\Trait_($this->name, ['stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
  7049. }
  7050. }
  7051. <?php
  7052. declare (strict_types=1);
  7053. namespace PHPUnitPHAR\PhpParser\Builder;
  7054. use PHPUnitPHAR\PhpParser\Builder;
  7055. use PHPUnitPHAR\PhpParser\BuilderHelpers;
  7056. use PHPUnitPHAR\PhpParser\Node;
  7057. use PHPUnitPHAR\PhpParser\Node\Stmt;
  7058. class Use_ implements Builder
  7059. {
  7060. protected Node\Name $name;
  7061. /** @var Stmt\Use_::TYPE_* */
  7062. protected int $type;
  7063. protected ?string $alias = null;
  7064. /**
  7065. * Creates a name use (alias) builder.
  7066. *
  7067. * @param Node\Name|string $name Name of the entity (namespace, class, function, constant) to alias
  7068. * @param Stmt\Use_::TYPE_* $type One of the Stmt\Use_::TYPE_* constants
  7069. */
  7070. public function __construct($name, int $type)
  7071. {
  7072. $this->name = BuilderHelpers::normalizeName($name);
  7073. $this->type = $type;
  7074. }
  7075. /**
  7076. * Sets alias for used name.
  7077. *
  7078. * @param string $alias Alias to use (last component of full name by default)
  7079. *
  7080. * @return $this The builder instance (for fluid interface)
  7081. */
  7082. public function as(string $alias)
  7083. {
  7084. $this->alias = $alias;
  7085. return $this;
  7086. }
  7087. /**
  7088. * Returns the built node.
  7089. *
  7090. * @return Stmt\Use_ The built node
  7091. */
  7092. public function getNode(): Node
  7093. {
  7094. return new Stmt\Use_([new Node\UseItem($this->name, $this->alias)], $this->type);
  7095. }
  7096. }
  7097. <?php
  7098. declare (strict_types=1);
  7099. namespace PHPUnitPHAR\PhpParser;
  7100. use PHPUnitPHAR\PhpParser\Node\Arg;
  7101. use PHPUnitPHAR\PhpParser\Node\Expr;
  7102. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\Concat;
  7103. use PHPUnitPHAR\PhpParser\Node\Identifier;
  7104. use PHPUnitPHAR\PhpParser\Node\Name;
  7105. use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
  7106. use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
  7107. class BuilderFactory
  7108. {
  7109. /**
  7110. * Creates an attribute node.
  7111. *
  7112. * @param string|Name $name Name of the attribute
  7113. * @param array $args Attribute named arguments
  7114. */
  7115. public function attribute($name, array $args = []): Node\Attribute
  7116. {
  7117. return new Node\Attribute(BuilderHelpers::normalizeName($name), $this->args($args));
  7118. }
  7119. /**
  7120. * Creates a namespace builder.
  7121. *
  7122. * @param null|string|Node\Name $name Name of the namespace
  7123. *
  7124. * @return Builder\Namespace_ The created namespace builder
  7125. */
  7126. public function namespace($name): Builder\Namespace_
  7127. {
  7128. return new Builder\Namespace_($name);
  7129. }
  7130. /**
  7131. * Creates a class builder.
  7132. *
  7133. * @param string $name Name of the class
  7134. *
  7135. * @return Builder\Class_ The created class builder
  7136. */
  7137. public function class(string $name): Builder\Class_
  7138. {
  7139. return new Builder\Class_($name);
  7140. }
  7141. /**
  7142. * Creates an interface builder.
  7143. *
  7144. * @param string $name Name of the interface
  7145. *
  7146. * @return Builder\Interface_ The created interface builder
  7147. */
  7148. public function interface(string $name): Builder\Interface_
  7149. {
  7150. return new Builder\Interface_($name);
  7151. }
  7152. /**
  7153. * Creates a trait builder.
  7154. *
  7155. * @param string $name Name of the trait
  7156. *
  7157. * @return Builder\Trait_ The created trait builder
  7158. */
  7159. public function trait(string $name): Builder\Trait_
  7160. {
  7161. return new Builder\Trait_($name);
  7162. }
  7163. /**
  7164. * Creates an enum builder.
  7165. *
  7166. * @param string $name Name of the enum
  7167. *
  7168. * @return Builder\Enum_ The created enum builder
  7169. */
  7170. public function enum(string $name): Builder\Enum_
  7171. {
  7172. return new Builder\Enum_($name);
  7173. }
  7174. /**
  7175. * Creates a trait use builder.
  7176. *
  7177. * @param Node\Name|string ...$traits Trait names
  7178. *
  7179. * @return Builder\TraitUse The created trait use builder
  7180. */
  7181. public function useTrait(...$traits): Builder\TraitUse
  7182. {
  7183. return new Builder\TraitUse(...$traits);
  7184. }
  7185. /**
  7186. * Creates a trait use adaptation builder.
  7187. *
  7188. * @param Node\Name|string|null $trait Trait name
  7189. * @param Node\Identifier|string $method Method name
  7190. *
  7191. * @return Builder\TraitUseAdaptation The created trait use adaptation builder
  7192. */
  7193. public function traitUseAdaptation($trait, $method = null): Builder\TraitUseAdaptation
  7194. {
  7195. if ($method === null) {
  7196. $method = $trait;
  7197. $trait = null;
  7198. }
  7199. return new Builder\TraitUseAdaptation($trait, $method);
  7200. }
  7201. /**
  7202. * Creates a method builder.
  7203. *
  7204. * @param string $name Name of the method
  7205. *
  7206. * @return Builder\Method The created method builder
  7207. */
  7208. public function method(string $name): Builder\Method
  7209. {
  7210. return new Builder\Method($name);
  7211. }
  7212. /**
  7213. * Creates a parameter builder.
  7214. *
  7215. * @param string $name Name of the parameter
  7216. *
  7217. * @return Builder\Param The created parameter builder
  7218. */
  7219. public function param(string $name): Builder\Param
  7220. {
  7221. return new Builder\Param($name);
  7222. }
  7223. /**
  7224. * Creates a property builder.
  7225. *
  7226. * @param string $name Name of the property
  7227. *
  7228. * @return Builder\Property The created property builder
  7229. */
  7230. public function property(string $name): Builder\Property
  7231. {
  7232. return new Builder\Property($name);
  7233. }
  7234. /**
  7235. * Creates a function builder.
  7236. *
  7237. * @param string $name Name of the function
  7238. *
  7239. * @return Builder\Function_ The created function builder
  7240. */
  7241. public function function(string $name): Builder\Function_
  7242. {
  7243. return new Builder\Function_($name);
  7244. }
  7245. /**
  7246. * Creates a namespace/class use builder.
  7247. *
  7248. * @param Node\Name|string $name Name of the entity (namespace or class) to alias
  7249. *
  7250. * @return Builder\Use_ The created use builder
  7251. */
  7252. public function use($name): Builder\Use_
  7253. {
  7254. return new Builder\Use_($name, Use_::TYPE_NORMAL);
  7255. }
  7256. /**
  7257. * Creates a function use builder.
  7258. *
  7259. * @param Node\Name|string $name Name of the function to alias
  7260. *
  7261. * @return Builder\Use_ The created use function builder
  7262. */
  7263. public function useFunction($name): Builder\Use_
  7264. {
  7265. return new Builder\Use_($name, Use_::TYPE_FUNCTION);
  7266. }
  7267. /**
  7268. * Creates a constant use builder.
  7269. *
  7270. * @param Node\Name|string $name Name of the const to alias
  7271. *
  7272. * @return Builder\Use_ The created use const builder
  7273. */
  7274. public function useConst($name): Builder\Use_
  7275. {
  7276. return new Builder\Use_($name, Use_::TYPE_CONSTANT);
  7277. }
  7278. /**
  7279. * Creates a class constant builder.
  7280. *
  7281. * @param string|Identifier $name Name
  7282. * @param Node\Expr|bool|null|int|float|string|array $value Value
  7283. *
  7284. * @return Builder\ClassConst The created use const builder
  7285. */
  7286. public function classConst($name, $value): Builder\ClassConst
  7287. {
  7288. return new Builder\ClassConst($name, $value);
  7289. }
  7290. /**
  7291. * Creates an enum case builder.
  7292. *
  7293. * @param string|Identifier $name Name
  7294. *
  7295. * @return Builder\EnumCase The created use const builder
  7296. */
  7297. public function enumCase($name): Builder\EnumCase
  7298. {
  7299. return new Builder\EnumCase($name);
  7300. }
  7301. /**
  7302. * Creates node a for a literal value.
  7303. *
  7304. * @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value
  7305. */
  7306. public function val($value): Expr
  7307. {
  7308. return BuilderHelpers::normalizeValue($value);
  7309. }
  7310. /**
  7311. * Creates variable node.
  7312. *
  7313. * @param string|Expr $name Name
  7314. */
  7315. public function var($name): Expr\Variable
  7316. {
  7317. if (!\is_string($name) && !$name instanceof Expr) {
  7318. throw new \LogicException('Variable name must be string or Expr');
  7319. }
  7320. return new Expr\Variable($name);
  7321. }
  7322. /**
  7323. * Normalizes an argument list.
  7324. *
  7325. * Creates Arg nodes for all arguments and converts literal values to expressions.
  7326. *
  7327. * @param array $args List of arguments to normalize
  7328. *
  7329. * @return list<Arg>
  7330. */
  7331. public function args(array $args): array
  7332. {
  7333. $normalizedArgs = [];
  7334. foreach ($args as $key => $arg) {
  7335. if (!$arg instanceof Arg) {
  7336. $arg = new Arg(BuilderHelpers::normalizeValue($arg));
  7337. }
  7338. if (\is_string($key)) {
  7339. $arg->name = BuilderHelpers::normalizeIdentifier($key);
  7340. }
  7341. $normalizedArgs[] = $arg;
  7342. }
  7343. return $normalizedArgs;
  7344. }
  7345. /**
  7346. * Creates a function call node.
  7347. *
  7348. * @param string|Name|Expr $name Function name
  7349. * @param array $args Function arguments
  7350. */
  7351. public function funcCall($name, array $args = []): Expr\FuncCall
  7352. {
  7353. return new Expr\FuncCall(BuilderHelpers::normalizeNameOrExpr($name), $this->args($args));
  7354. }
  7355. /**
  7356. * Creates a method call node.
  7357. *
  7358. * @param Expr $var Variable the method is called on
  7359. * @param string|Identifier|Expr $name Method name
  7360. * @param array $args Method arguments
  7361. */
  7362. public function methodCall(Expr $var, $name, array $args = []): Expr\MethodCall
  7363. {
  7364. return new Expr\MethodCall($var, BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
  7365. }
  7366. /**
  7367. * Creates a static method call node.
  7368. *
  7369. * @param string|Name|Expr $class Class name
  7370. * @param string|Identifier|Expr $name Method name
  7371. * @param array $args Method arguments
  7372. */
  7373. public function staticCall($class, $name, array $args = []): Expr\StaticCall
  7374. {
  7375. return new Expr\StaticCall(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
  7376. }
  7377. /**
  7378. * Creates an object creation node.
  7379. *
  7380. * @param string|Name|Expr $class Class name
  7381. * @param array $args Constructor arguments
  7382. */
  7383. public function new($class, array $args = []): Expr\New_
  7384. {
  7385. return new Expr\New_(BuilderHelpers::normalizeNameOrExpr($class), $this->args($args));
  7386. }
  7387. /**
  7388. * Creates a constant fetch node.
  7389. *
  7390. * @param string|Name $name Constant name
  7391. */
  7392. public function constFetch($name): Expr\ConstFetch
  7393. {
  7394. return new Expr\ConstFetch(BuilderHelpers::normalizeName($name));
  7395. }
  7396. /**
  7397. * Creates a property fetch node.
  7398. *
  7399. * @param Expr $var Variable holding object
  7400. * @param string|Identifier|Expr $name Property name
  7401. */
  7402. public function propertyFetch(Expr $var, $name): Expr\PropertyFetch
  7403. {
  7404. return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name));
  7405. }
  7406. /**
  7407. * Creates a class constant fetch node.
  7408. *
  7409. * @param string|Name|Expr $class Class name
  7410. * @param string|Identifier|Expr $name Constant name
  7411. */
  7412. public function classConstFetch($class, $name): Expr\ClassConstFetch
  7413. {
  7414. return new Expr\ClassConstFetch(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name));
  7415. }
  7416. /**
  7417. * Creates nested Concat nodes from a list of expressions.
  7418. *
  7419. * @param Expr|string ...$exprs Expressions or literal strings
  7420. */
  7421. public function concat(...$exprs): Concat
  7422. {
  7423. $numExprs = count($exprs);
  7424. if ($numExprs < 2) {
  7425. throw new \LogicException('Expected at least two expressions');
  7426. }
  7427. $lastConcat = $this->normalizeStringExpr($exprs[0]);
  7428. for ($i = 1; $i < $numExprs; $i++) {
  7429. $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i]));
  7430. }
  7431. return $lastConcat;
  7432. }
  7433. /**
  7434. * @param string|Expr $expr
  7435. */
  7436. private function normalizeStringExpr($expr): Expr
  7437. {
  7438. if ($expr instanceof Expr) {
  7439. return $expr;
  7440. }
  7441. if (\is_string($expr)) {
  7442. return new String_($expr);
  7443. }
  7444. throw new \LogicException('Expected string or Expr');
  7445. }
  7446. }
  7447. <?php
  7448. declare (strict_types=1);
  7449. namespace PHPUnitPHAR\PhpParser;
  7450. use PHPUnitPHAR\PhpParser\Node\ComplexType;
  7451. use PHPUnitPHAR\PhpParser\Node\Expr;
  7452. use PHPUnitPHAR\PhpParser\Node\Identifier;
  7453. use PHPUnitPHAR\PhpParser\Node\Name;
  7454. use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
  7455. use PHPUnitPHAR\PhpParser\Node\NullableType;
  7456. use PHPUnitPHAR\PhpParser\Node\Scalar;
  7457. use PHPUnitPHAR\PhpParser\Node\Stmt;
  7458. /**
  7459. * This class defines helpers used in the implementation of builders. Don't use it directly.
  7460. *
  7461. * @internal
  7462. */
  7463. final class BuilderHelpers
  7464. {
  7465. /**
  7466. * Normalizes a node: Converts builder objects to nodes.
  7467. *
  7468. * @param Node|Builder $node The node to normalize
  7469. *
  7470. * @return Node The normalized node
  7471. */
  7472. public static function normalizeNode($node): Node
  7473. {
  7474. if ($node instanceof Builder) {
  7475. return $node->getNode();
  7476. }
  7477. if ($node instanceof Node) {
  7478. return $node;
  7479. }
  7480. throw new \LogicException('Expected node or builder object');
  7481. }
  7482. /**
  7483. * Normalizes a node to a statement.
  7484. *
  7485. * Expressions are wrapped in a Stmt\Expression node.
  7486. *
  7487. * @param Node|Builder $node The node to normalize
  7488. *
  7489. * @return Stmt The normalized statement node
  7490. */
  7491. public static function normalizeStmt($node): Stmt
  7492. {
  7493. $node = self::normalizeNode($node);
  7494. if ($node instanceof Stmt) {
  7495. return $node;
  7496. }
  7497. if ($node instanceof Expr) {
  7498. return new Stmt\Expression($node);
  7499. }
  7500. throw new \LogicException('Expected statement or expression node');
  7501. }
  7502. /**
  7503. * Normalizes strings to Identifier.
  7504. *
  7505. * @param string|Identifier $name The identifier to normalize
  7506. *
  7507. * @return Identifier The normalized identifier
  7508. */
  7509. public static function normalizeIdentifier($name): Identifier
  7510. {
  7511. if ($name instanceof Identifier) {
  7512. return $name;
  7513. }
  7514. if (\is_string($name)) {
  7515. return new Identifier($name);
  7516. }
  7517. throw new \LogicException('Expected string or instance of Node\Identifier');
  7518. }
  7519. /**
  7520. * Normalizes strings to Identifier, also allowing expressions.
  7521. *
  7522. * @param string|Identifier|Expr $name The identifier to normalize
  7523. *
  7524. * @return Identifier|Expr The normalized identifier or expression
  7525. */
  7526. public static function normalizeIdentifierOrExpr($name)
  7527. {
  7528. if ($name instanceof Identifier || $name instanceof Expr) {
  7529. return $name;
  7530. }
  7531. if (\is_string($name)) {
  7532. return new Identifier($name);
  7533. }
  7534. throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr');
  7535. }
  7536. /**
  7537. * Normalizes a name: Converts string names to Name nodes.
  7538. *
  7539. * @param Name|string $name The name to normalize
  7540. *
  7541. * @return Name The normalized name
  7542. */
  7543. public static function normalizeName($name): Name
  7544. {
  7545. if ($name instanceof Name) {
  7546. return $name;
  7547. }
  7548. if (is_string($name)) {
  7549. if (!$name) {
  7550. throw new \LogicException('Name cannot be empty');
  7551. }
  7552. if ($name[0] === '\\') {
  7553. return new Name\FullyQualified(substr($name, 1));
  7554. }
  7555. if (0 === strpos($name, 'namespace\\')) {
  7556. return new Name\Relative(substr($name, strlen('namespace\\')));
  7557. }
  7558. return new Name($name);
  7559. }
  7560. throw new \LogicException('Name must be a string or an instance of Node\Name');
  7561. }
  7562. /**
  7563. * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
  7564. *
  7565. * @param Expr|Name|string $name The name to normalize
  7566. *
  7567. * @return Name|Expr The normalized name or expression
  7568. */
  7569. public static function normalizeNameOrExpr($name)
  7570. {
  7571. if ($name instanceof Expr) {
  7572. return $name;
  7573. }
  7574. if (!is_string($name) && !$name instanceof Name) {
  7575. throw new \LogicException('Name must be a string or an instance of Node\Name or Node\Expr');
  7576. }
  7577. return self::normalizeName($name);
  7578. }
  7579. /**
  7580. * Normalizes a type: Converts plain-text type names into proper AST representation.
  7581. *
  7582. * In particular, builtin types become Identifiers, custom types become Names and nullables
  7583. * are wrapped in NullableType nodes.
  7584. *
  7585. * @param string|Name|Identifier|ComplexType $type The type to normalize
  7586. *
  7587. * @return Name|Identifier|ComplexType The normalized type
  7588. */
  7589. public static function normalizeType($type)
  7590. {
  7591. if (!is_string($type)) {
  7592. if (!$type instanceof Name && !$type instanceof Identifier && !$type instanceof ComplexType) {
  7593. throw new \LogicException('Type must be a string, or an instance of Name, Identifier or ComplexType');
  7594. }
  7595. return $type;
  7596. }
  7597. $nullable = \false;
  7598. if (strlen($type) > 0 && $type[0] === '?') {
  7599. $nullable = \true;
  7600. $type = substr($type, 1);
  7601. }
  7602. $builtinTypes = ['array', 'callable', 'bool', 'int', 'float', 'string', 'iterable', 'void', 'object', 'null', 'false', 'mixed', 'never', 'true'];
  7603. $lowerType = strtolower($type);
  7604. if (in_array($lowerType, $builtinTypes)) {
  7605. $type = new Identifier($lowerType);
  7606. } else {
  7607. $type = self::normalizeName($type);
  7608. }
  7609. $notNullableTypes = ['void', 'mixed', 'never'];
  7610. if ($nullable && in_array((string) $type, $notNullableTypes)) {
  7611. throw new \LogicException(sprintf('%s type cannot be nullable', $type));
  7612. }
  7613. return $nullable ? new NullableType($type) : $type;
  7614. }
  7615. /**
  7616. * Normalizes a value: Converts nulls, booleans, integers,
  7617. * floats, strings and arrays into their respective nodes
  7618. *
  7619. * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value The value to normalize
  7620. *
  7621. * @return Expr The normalized value
  7622. */
  7623. public static function normalizeValue($value): Expr
  7624. {
  7625. if ($value instanceof Node\Expr) {
  7626. return $value;
  7627. }
  7628. if (is_null($value)) {
  7629. return new Expr\ConstFetch(new Name('null'));
  7630. }
  7631. if (is_bool($value)) {
  7632. return new Expr\ConstFetch(new Name($value ? 'true' : 'false'));
  7633. }
  7634. if (is_int($value)) {
  7635. return new Scalar\Int_($value);
  7636. }
  7637. if (is_float($value)) {
  7638. return new Scalar\Float_($value);
  7639. }
  7640. if (is_string($value)) {
  7641. return new Scalar\String_($value);
  7642. }
  7643. if (is_array($value)) {
  7644. $items = [];
  7645. $lastKey = -1;
  7646. foreach ($value as $itemKey => $itemValue) {
  7647. // for consecutive, numeric keys don't generate keys
  7648. if (null !== $lastKey && ++$lastKey === $itemKey) {
  7649. $items[] = new Node\ArrayItem(self::normalizeValue($itemValue));
  7650. } else {
  7651. $lastKey = null;
  7652. $items[] = new Node\ArrayItem(self::normalizeValue($itemValue), self::normalizeValue($itemKey));
  7653. }
  7654. }
  7655. return new Expr\Array_($items);
  7656. }
  7657. if ($value instanceof \UnitEnum) {
  7658. return new Expr\ClassConstFetch(new FullyQualified(\get_class($value)), new Identifier($value->name));
  7659. }
  7660. throw new \LogicException('Invalid value');
  7661. }
  7662. /**
  7663. * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
  7664. *
  7665. * @param Comment\Doc|string $docComment The doc comment to normalize
  7666. *
  7667. * @return Comment\Doc The normalized doc comment
  7668. */
  7669. public static function normalizeDocComment($docComment): Comment\Doc
  7670. {
  7671. if ($docComment instanceof Comment\Doc) {
  7672. return $docComment;
  7673. }
  7674. if (is_string($docComment)) {
  7675. return new Comment\Doc($docComment);
  7676. }
  7677. throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
  7678. }
  7679. /**
  7680. * Normalizes a attribute: Converts attribute to the Attribute Group if needed.
  7681. *
  7682. * @param Node\Attribute|Node\AttributeGroup $attribute
  7683. *
  7684. * @return Node\AttributeGroup The Attribute Group
  7685. */
  7686. public static function normalizeAttribute($attribute): Node\AttributeGroup
  7687. {
  7688. if ($attribute instanceof Node\AttributeGroup) {
  7689. return $attribute;
  7690. }
  7691. if (!$attribute instanceof Node\Attribute) {
  7692. throw new \LogicException('Attribute must be an instance of PhpParser\Node\Attribute or PhpParser\Node\AttributeGroup');
  7693. }
  7694. return new Node\AttributeGroup([$attribute]);
  7695. }
  7696. /**
  7697. * Adds a modifier and returns new modifier bitmask.
  7698. *
  7699. * @param int $modifiers Existing modifiers
  7700. * @param int $modifier Modifier to set
  7701. *
  7702. * @return int New modifiers
  7703. */
  7704. public static function addModifier(int $modifiers, int $modifier): int
  7705. {
  7706. Modifiers::verifyModifier($modifiers, $modifier);
  7707. return $modifiers | $modifier;
  7708. }
  7709. /**
  7710. * Adds a modifier and returns new modifier bitmask.
  7711. * @return int New modifiers
  7712. */
  7713. public static function addClassModifier(int $existingModifiers, int $modifierToSet): int
  7714. {
  7715. Modifiers::verifyClassModifier($existingModifiers, $modifierToSet);
  7716. return $existingModifiers | $modifierToSet;
  7717. }
  7718. }
  7719. <?php
  7720. declare (strict_types=1);
  7721. namespace PHPUnitPHAR\PhpParser;
  7722. class Comment implements \JsonSerializable
  7723. {
  7724. protected string $text;
  7725. protected int $startLine;
  7726. protected int $startFilePos;
  7727. protected int $startTokenPos;
  7728. protected int $endLine;
  7729. protected int $endFilePos;
  7730. protected int $endTokenPos;
  7731. /**
  7732. * Constructs a comment node.
  7733. *
  7734. * @param string $text Comment text (including comment delimiters like /*)
  7735. * @param int $startLine Line number the comment started on
  7736. * @param int $startFilePos File offset the comment started on
  7737. * @param int $startTokenPos Token offset the comment started on
  7738. */
  7739. public function __construct(string $text, int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1, int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1)
  7740. {
  7741. $this->text = $text;
  7742. $this->startLine = $startLine;
  7743. $this->startFilePos = $startFilePos;
  7744. $this->startTokenPos = $startTokenPos;
  7745. $this->endLine = $endLine;
  7746. $this->endFilePos = $endFilePos;
  7747. $this->endTokenPos = $endTokenPos;
  7748. }
  7749. /**
  7750. * Gets the comment text.
  7751. *
  7752. * @return string The comment text (including comment delimiters like /*)
  7753. */
  7754. public function getText(): string
  7755. {
  7756. return $this->text;
  7757. }
  7758. /**
  7759. * Gets the line number the comment started on.
  7760. *
  7761. * @return int Line number (or -1 if not available)
  7762. * @phpstan-return -1|positive-int
  7763. */
  7764. public function getStartLine(): int
  7765. {
  7766. return $this->startLine;
  7767. }
  7768. /**
  7769. * Gets the file offset the comment started on.
  7770. *
  7771. * @return int File offset (or -1 if not available)
  7772. */
  7773. public function getStartFilePos(): int
  7774. {
  7775. return $this->startFilePos;
  7776. }
  7777. /**
  7778. * Gets the token offset the comment started on.
  7779. *
  7780. * @return int Token offset (or -1 if not available)
  7781. */
  7782. public function getStartTokenPos(): int
  7783. {
  7784. return $this->startTokenPos;
  7785. }
  7786. /**
  7787. * Gets the line number the comment ends on.
  7788. *
  7789. * @return int Line number (or -1 if not available)
  7790. * @phpstan-return -1|positive-int
  7791. */
  7792. public function getEndLine(): int
  7793. {
  7794. return $this->endLine;
  7795. }
  7796. /**
  7797. * Gets the file offset the comment ends on.
  7798. *
  7799. * @return int File offset (or -1 if not available)
  7800. */
  7801. public function getEndFilePos(): int
  7802. {
  7803. return $this->endFilePos;
  7804. }
  7805. /**
  7806. * Gets the token offset the comment ends on.
  7807. *
  7808. * @return int Token offset (or -1 if not available)
  7809. */
  7810. public function getEndTokenPos(): int
  7811. {
  7812. return $this->endTokenPos;
  7813. }
  7814. /**
  7815. * Gets the comment text.
  7816. *
  7817. * @return string The comment text (including comment delimiters like /*)
  7818. */
  7819. public function __toString(): string
  7820. {
  7821. return $this->text;
  7822. }
  7823. /**
  7824. * Gets the reformatted comment text.
  7825. *
  7826. * "Reformatted" here means that we try to clean up the whitespace at the
  7827. * starts of the lines. This is necessary because we receive the comments
  7828. * without leading whitespace on the first line, but with leading whitespace
  7829. * on all subsequent lines.
  7830. *
  7831. * Additionally, this normalizes CRLF newlines to LF newlines.
  7832. */
  7833. public function getReformattedText(): string
  7834. {
  7835. $text = str_replace("\r\n", "\n", $this->text);
  7836. $newlinePos = strpos($text, "\n");
  7837. if (\false === $newlinePos) {
  7838. // Single line comments don't need further processing
  7839. return $text;
  7840. }
  7841. if (preg_match('(^.*(?:\n\s+\*.*)+$)', $text)) {
  7842. // Multi line comment of the type
  7843. //
  7844. // /*
  7845. // * Some text.
  7846. // * Some more text.
  7847. // */
  7848. //
  7849. // is handled by replacing the whitespace sequences before the * by a single space
  7850. return preg_replace('(^\s+\*)m', ' *', $text);
  7851. }
  7852. if (preg_match('(^/\*\*?\s*\n)', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
  7853. // Multi line comment of the type
  7854. //
  7855. // /*
  7856. // Some text.
  7857. // Some more text.
  7858. // */
  7859. //
  7860. // is handled by removing the whitespace sequence on the line before the closing
  7861. // */ on all lines. So if the last line is " */", then " " is removed at the
  7862. // start of all lines.
  7863. return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text);
  7864. }
  7865. if (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) {
  7866. // Multi line comment of the type
  7867. //
  7868. // /* Some text.
  7869. // Some more text.
  7870. // Indented text.
  7871. // Even more text. */
  7872. //
  7873. // is handled by removing the difference between the shortest whitespace prefix on all
  7874. // lines and the length of the "/* " opening sequence.
  7875. $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1));
  7876. $removeLen = $prefixLen - strlen($matches[0]);
  7877. return preg_replace('(^\s{' . $removeLen . '})m', '', $text);
  7878. }
  7879. // No idea how to format this comment, so simply return as is
  7880. return $text;
  7881. }
  7882. /**
  7883. * Get length of shortest whitespace prefix (at the start of a line).
  7884. *
  7885. * If there is a line with no prefix whitespace, 0 is a valid return value.
  7886. *
  7887. * @param string $str String to check
  7888. * @return int Length in characters. Tabs count as single characters.
  7889. */
  7890. private function getShortestWhitespacePrefixLen(string $str): int
  7891. {
  7892. $lines = explode("\n", $str);
  7893. $shortestPrefixLen = \PHP_INT_MAX;
  7894. foreach ($lines as $line) {
  7895. preg_match('(^\s*)', $line, $matches);
  7896. $prefixLen = strlen($matches[0]);
  7897. if ($prefixLen < $shortestPrefixLen) {
  7898. $shortestPrefixLen = $prefixLen;
  7899. }
  7900. }
  7901. return $shortestPrefixLen;
  7902. }
  7903. /**
  7904. * @return array{nodeType:string, text:mixed, line:mixed, filePos:mixed}
  7905. */
  7906. public function jsonSerialize(): array
  7907. {
  7908. // Technically not a node, but we make it look like one anyway
  7909. $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
  7910. return [
  7911. 'nodeType' => $type,
  7912. 'text' => $this->text,
  7913. // TODO: Rename these to include "start".
  7914. 'line' => $this->startLine,
  7915. 'filePos' => $this->startFilePos,
  7916. 'tokenPos' => $this->startTokenPos,
  7917. 'endLine' => $this->endLine,
  7918. 'endFilePos' => $this->endFilePos,
  7919. 'endTokenPos' => $this->endTokenPos,
  7920. ];
  7921. }
  7922. }
  7923. <?php
  7924. declare (strict_types=1);
  7925. namespace PHPUnitPHAR\PhpParser\Comment;
  7926. class Doc extends \PHPUnitPHAR\PhpParser\Comment
  7927. {
  7928. }
  7929. <?php
  7930. declare (strict_types=1);
  7931. namespace PHPUnitPHAR\PhpParser;
  7932. class ConstExprEvaluationException extends \Exception
  7933. {
  7934. }
  7935. <?php
  7936. declare (strict_types=1);
  7937. namespace PHPUnitPHAR\PhpParser;
  7938. use PHPUnitPHAR\PhpParser\Node\Expr;
  7939. use PHPUnitPHAR\PhpParser\Node\Scalar;
  7940. use function array_merge;
  7941. /**
  7942. * Evaluates constant expressions.
  7943. *
  7944. * This evaluator is able to evaluate all constant expressions (as defined by PHP), which can be
  7945. * evaluated without further context. If a subexpression is not of this type, a user-provided
  7946. * fallback evaluator is invoked. To support all constant expressions that are also supported by
  7947. * PHP (and not already handled by this class), the fallback evaluator must be able to handle the
  7948. * following node types:
  7949. *
  7950. * * All Scalar\MagicConst\* nodes.
  7951. * * Expr\ConstFetch nodes. Only null/false/true are already handled by this class.
  7952. * * Expr\ClassConstFetch nodes.
  7953. *
  7954. * The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate.
  7955. *
  7956. * The evaluation is dependent on runtime configuration in two respects: Firstly, floating
  7957. * point to string conversions are affected by the precision ini setting. Secondly, they are also
  7958. * affected by the LC_NUMERIC locale.
  7959. */
  7960. class ConstExprEvaluator
  7961. {
  7962. /** @var callable|null */
  7963. private $fallbackEvaluator;
  7964. /**
  7965. * Create a constant expression evaluator.
  7966. *
  7967. * The provided fallback evaluator is invoked whenever a subexpression cannot be evaluated. See
  7968. * class doc comment for more information.
  7969. *
  7970. * @param callable|null $fallbackEvaluator To call if subexpression cannot be evaluated
  7971. */
  7972. public function __construct(?callable $fallbackEvaluator = null)
  7973. {
  7974. $this->fallbackEvaluator = $fallbackEvaluator ?? function (Expr $expr) {
  7975. throw new ConstExprEvaluationException("Expression of type {$expr->getType()} cannot be evaluated");
  7976. };
  7977. }
  7978. /**
  7979. * Silently evaluates a constant expression into a PHP value.
  7980. *
  7981. * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException.
  7982. * The original source of the exception is available through getPrevious().
  7983. *
  7984. * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
  7985. * constructor will be invoked. By default, if no fallback is provided, an exception of type
  7986. * ConstExprEvaluationException is thrown.
  7987. *
  7988. * See class doc comment for caveats and limitations.
  7989. *
  7990. * @param Expr $expr Constant expression to evaluate
  7991. * @return mixed Result of evaluation
  7992. *
  7993. * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred
  7994. */
  7995. public function evaluateSilently(Expr $expr)
  7996. {
  7997. set_error_handler(function ($num, $str, $file, $line) {
  7998. throw new \ErrorException($str, 0, $num, $file, $line);
  7999. });
  8000. try {
  8001. return $this->evaluate($expr);
  8002. } catch (\Throwable $e) {
  8003. if (!$e instanceof ConstExprEvaluationException) {
  8004. $e = new ConstExprEvaluationException("An error occurred during constant expression evaluation", 0, $e);
  8005. }
  8006. throw $e;
  8007. } finally {
  8008. restore_error_handler();
  8009. }
  8010. }
  8011. /**
  8012. * Directly evaluates a constant expression into a PHP value.
  8013. *
  8014. * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these
  8015. * into a ConstExprEvaluationException.
  8016. *
  8017. * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
  8018. * constructor will be invoked. By default, if no fallback is provided, an exception of type
  8019. * ConstExprEvaluationException is thrown.
  8020. *
  8021. * See class doc comment for caveats and limitations.
  8022. *
  8023. * @param Expr $expr Constant expression to evaluate
  8024. * @return mixed Result of evaluation
  8025. *
  8026. * @throws ConstExprEvaluationException if the expression cannot be evaluated
  8027. */
  8028. public function evaluateDirectly(Expr $expr)
  8029. {
  8030. return $this->evaluate($expr);
  8031. }
  8032. /** @return mixed */
  8033. private function evaluate(Expr $expr)
  8034. {
  8035. if ($expr instanceof Scalar\Int_ || $expr instanceof Scalar\Float_ || $expr instanceof Scalar\String_) {
  8036. return $expr->value;
  8037. }
  8038. if ($expr instanceof Expr\Array_) {
  8039. return $this->evaluateArray($expr);
  8040. }
  8041. // Unary operators
  8042. if ($expr instanceof Expr\UnaryPlus) {
  8043. return +$this->evaluate($expr->expr);
  8044. }
  8045. if ($expr instanceof Expr\UnaryMinus) {
  8046. return -$this->evaluate($expr->expr);
  8047. }
  8048. if ($expr instanceof Expr\BooleanNot) {
  8049. return !$this->evaluate($expr->expr);
  8050. }
  8051. if ($expr instanceof Expr\BitwiseNot) {
  8052. return ~$this->evaluate($expr->expr);
  8053. }
  8054. if ($expr instanceof Expr\BinaryOp) {
  8055. return $this->evaluateBinaryOp($expr);
  8056. }
  8057. if ($expr instanceof Expr\Ternary) {
  8058. return $this->evaluateTernary($expr);
  8059. }
  8060. if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) {
  8061. return $this->evaluate($expr->var)[$this->evaluate($expr->dim)];
  8062. }
  8063. if ($expr instanceof Expr\ConstFetch) {
  8064. return $this->evaluateConstFetch($expr);
  8065. }
  8066. return ($this->fallbackEvaluator)($expr);
  8067. }
  8068. private function evaluateArray(Expr\Array_ $expr): array
  8069. {
  8070. $array = [];
  8071. foreach ($expr->items as $item) {
  8072. if (null !== $item->key) {
  8073. $array[$this->evaluate($item->key)] = $this->evaluate($item->value);
  8074. } elseif ($item->unpack) {
  8075. $array = array_merge($array, $this->evaluate($item->value));
  8076. } else {
  8077. $array[] = $this->evaluate($item->value);
  8078. }
  8079. }
  8080. return $array;
  8081. }
  8082. /** @return mixed */
  8083. private function evaluateTernary(Expr\Ternary $expr)
  8084. {
  8085. if (null === $expr->if) {
  8086. return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else);
  8087. }
  8088. return $this->evaluate($expr->cond) ? $this->evaluate($expr->if) : $this->evaluate($expr->else);
  8089. }
  8090. /** @return mixed */
  8091. private function evaluateBinaryOp(Expr\BinaryOp $expr)
  8092. {
  8093. if ($expr instanceof Expr\BinaryOp\Coalesce && $expr->left instanceof Expr\ArrayDimFetch) {
  8094. // This needs to be special cased to respect BP_VAR_IS fetch semantics
  8095. return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)] ?? $this->evaluate($expr->right);
  8096. }
  8097. // The evaluate() calls are repeated in each branch, because some of the operators are
  8098. // short-circuiting and evaluating the RHS in advance may be illegal in that case
  8099. $l = $expr->left;
  8100. $r = $expr->right;
  8101. switch ($expr->getOperatorSigil()) {
  8102. case '&':
  8103. return $this->evaluate($l) & $this->evaluate($r);
  8104. case '|':
  8105. return $this->evaluate($l) | $this->evaluate($r);
  8106. case '^':
  8107. return $this->evaluate($l) ^ $this->evaluate($r);
  8108. case '&&':
  8109. return $this->evaluate($l) && $this->evaluate($r);
  8110. case '||':
  8111. return $this->evaluate($l) || $this->evaluate($r);
  8112. case '??':
  8113. return $this->evaluate($l) ?? $this->evaluate($r);
  8114. case '.':
  8115. return $this->evaluate($l) . $this->evaluate($r);
  8116. case '/':
  8117. return $this->evaluate($l) / $this->evaluate($r);
  8118. case '==':
  8119. return $this->evaluate($l) == $this->evaluate($r);
  8120. case '>':
  8121. return $this->evaluate($l) > $this->evaluate($r);
  8122. case '>=':
  8123. return $this->evaluate($l) >= $this->evaluate($r);
  8124. case '===':
  8125. return $this->evaluate($l) === $this->evaluate($r);
  8126. case 'and':
  8127. return $this->evaluate($l) and $this->evaluate($r);
  8128. case 'or':
  8129. return $this->evaluate($l) or $this->evaluate($r);
  8130. case 'xor':
  8131. return $this->evaluate($l) xor $this->evaluate($r);
  8132. case '-':
  8133. return $this->evaluate($l) - $this->evaluate($r);
  8134. case '%':
  8135. return $this->evaluate($l) % $this->evaluate($r);
  8136. case '*':
  8137. return $this->evaluate($l) * $this->evaluate($r);
  8138. case '!=':
  8139. return $this->evaluate($l) != $this->evaluate($r);
  8140. case '!==':
  8141. return $this->evaluate($l) !== $this->evaluate($r);
  8142. case '+':
  8143. return $this->evaluate($l) + $this->evaluate($r);
  8144. case '**':
  8145. return $this->evaluate($l) ** $this->evaluate($r);
  8146. case '<<':
  8147. return $this->evaluate($l) << $this->evaluate($r);
  8148. case '>>':
  8149. return $this->evaluate($l) >> $this->evaluate($r);
  8150. case '<':
  8151. return $this->evaluate($l) < $this->evaluate($r);
  8152. case '<=':
  8153. return $this->evaluate($l) <= $this->evaluate($r);
  8154. case '<=>':
  8155. return $this->evaluate($l) <=> $this->evaluate($r);
  8156. }
  8157. throw new \Exception('Should not happen');
  8158. }
  8159. /** @return mixed */
  8160. private function evaluateConstFetch(Expr\ConstFetch $expr)
  8161. {
  8162. $name = $expr->name->toLowerString();
  8163. switch ($name) {
  8164. case 'null':
  8165. return null;
  8166. case 'false':
  8167. return \false;
  8168. case 'true':
  8169. return \true;
  8170. }
  8171. return ($this->fallbackEvaluator)($expr);
  8172. }
  8173. }
  8174. <?php
  8175. declare (strict_types=1);
  8176. namespace PHPUnitPHAR\PhpParser;
  8177. class Error extends \RuntimeException
  8178. {
  8179. protected string $rawMessage;
  8180. /** @var array<string, mixed> */
  8181. protected array $attributes;
  8182. /**
  8183. * Creates an Exception signifying a parse error.
  8184. *
  8185. * @param string $message Error message
  8186. * @param array<string, mixed> $attributes Attributes of node/token where error occurred
  8187. */
  8188. public function __construct(string $message, array $attributes = [])
  8189. {
  8190. $this->rawMessage = $message;
  8191. $this->attributes = $attributes;
  8192. $this->updateMessage();
  8193. }
  8194. /**
  8195. * Gets the error message
  8196. *
  8197. * @return string Error message
  8198. */
  8199. public function getRawMessage(): string
  8200. {
  8201. return $this->rawMessage;
  8202. }
  8203. /**
  8204. * Gets the line the error starts in.
  8205. *
  8206. * @return int Error start line
  8207. * @phpstan-return -1|positive-int
  8208. */
  8209. public function getStartLine(): int
  8210. {
  8211. return $this->attributes['startLine'] ?? -1;
  8212. }
  8213. /**
  8214. * Gets the line the error ends in.
  8215. *
  8216. * @return int Error end line
  8217. * @phpstan-return -1|positive-int
  8218. */
  8219. public function getEndLine(): int
  8220. {
  8221. return $this->attributes['endLine'] ?? -1;
  8222. }
  8223. /**
  8224. * Gets the attributes of the node/token the error occurred at.
  8225. *
  8226. * @return array<string, mixed>
  8227. */
  8228. public function getAttributes(): array
  8229. {
  8230. return $this->attributes;
  8231. }
  8232. /**
  8233. * Sets the attributes of the node/token the error occurred at.
  8234. *
  8235. * @param array<string, mixed> $attributes
  8236. */
  8237. public function setAttributes(array $attributes): void
  8238. {
  8239. $this->attributes = $attributes;
  8240. $this->updateMessage();
  8241. }
  8242. /**
  8243. * Sets the line of the PHP file the error occurred in.
  8244. *
  8245. * @param string $message Error message
  8246. */
  8247. public function setRawMessage(string $message): void
  8248. {
  8249. $this->rawMessage = $message;
  8250. $this->updateMessage();
  8251. }
  8252. /**
  8253. * Sets the line the error starts in.
  8254. *
  8255. * @param int $line Error start line
  8256. */
  8257. public function setStartLine(int $line): void
  8258. {
  8259. $this->attributes['startLine'] = $line;
  8260. $this->updateMessage();
  8261. }
  8262. /**
  8263. * Returns whether the error has start and end column information.
  8264. *
  8265. * For column information enable the startFilePos and endFilePos in the lexer options.
  8266. */
  8267. public function hasColumnInfo(): bool
  8268. {
  8269. return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']);
  8270. }
  8271. /**
  8272. * Gets the start column (1-based) into the line where the error started.
  8273. *
  8274. * @param string $code Source code of the file
  8275. */
  8276. public function getStartColumn(string $code): int
  8277. {
  8278. if (!$this->hasColumnInfo()) {
  8279. throw new \RuntimeException('Error does not have column information');
  8280. }
  8281. return $this->toColumn($code, $this->attributes['startFilePos']);
  8282. }
  8283. /**
  8284. * Gets the end column (1-based) into the line where the error ended.
  8285. *
  8286. * @param string $code Source code of the file
  8287. */
  8288. public function getEndColumn(string $code): int
  8289. {
  8290. if (!$this->hasColumnInfo()) {
  8291. throw new \RuntimeException('Error does not have column information');
  8292. }
  8293. return $this->toColumn($code, $this->attributes['endFilePos']);
  8294. }
  8295. /**
  8296. * Formats message including line and column information.
  8297. *
  8298. * @param string $code Source code associated with the error, for calculation of the columns
  8299. *
  8300. * @return string Formatted message
  8301. */
  8302. public function getMessageWithColumnInfo(string $code): string
  8303. {
  8304. return sprintf('%s from %d:%d to %d:%d', $this->getRawMessage(), $this->getStartLine(), $this->getStartColumn($code), $this->getEndLine(), $this->getEndColumn($code));
  8305. }
  8306. /**
  8307. * Converts a file offset into a column.
  8308. *
  8309. * @param string $code Source code that $pos indexes into
  8310. * @param int $pos 0-based position in $code
  8311. *
  8312. * @return int 1-based column (relative to start of line)
  8313. */
  8314. private function toColumn(string $code, int $pos): int
  8315. {
  8316. if ($pos > strlen($code)) {
  8317. throw new \RuntimeException('Invalid position information');
  8318. }
  8319. $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
  8320. if (\false === $lineStartPos) {
  8321. $lineStartPos = -1;
  8322. }
  8323. return $pos - $lineStartPos;
  8324. }
  8325. /**
  8326. * Updates the exception message after a change to rawMessage or rawLine.
  8327. */
  8328. protected function updateMessage(): void
  8329. {
  8330. $this->message = $this->rawMessage;
  8331. if (-1 === $this->getStartLine()) {
  8332. $this->message .= ' on unknown line';
  8333. } else {
  8334. $this->message .= ' on line ' . $this->getStartLine();
  8335. }
  8336. }
  8337. }
  8338. <?php
  8339. declare (strict_types=1);
  8340. namespace PHPUnitPHAR\PhpParser;
  8341. interface ErrorHandler
  8342. {
  8343. /**
  8344. * Handle an error generated during lexing, parsing or some other operation.
  8345. *
  8346. * @param Error $error The error that needs to be handled
  8347. */
  8348. public function handleError(Error $error): void;
  8349. }
  8350. <?php
  8351. declare (strict_types=1);
  8352. namespace PHPUnitPHAR\PhpParser\ErrorHandler;
  8353. use PHPUnitPHAR\PhpParser\Error;
  8354. use PHPUnitPHAR\PhpParser\ErrorHandler;
  8355. /**
  8356. * Error handler that collects all errors into an array.
  8357. *
  8358. * This allows graceful handling of errors.
  8359. */
  8360. class Collecting implements ErrorHandler
  8361. {
  8362. /** @var Error[] Collected errors */
  8363. private array $errors = [];
  8364. public function handleError(Error $error): void
  8365. {
  8366. $this->errors[] = $error;
  8367. }
  8368. /**
  8369. * Get collected errors.
  8370. *
  8371. * @return Error[]
  8372. */
  8373. public function getErrors(): array
  8374. {
  8375. return $this->errors;
  8376. }
  8377. /**
  8378. * Check whether there are any errors.
  8379. */
  8380. public function hasErrors(): bool
  8381. {
  8382. return !empty($this->errors);
  8383. }
  8384. /**
  8385. * Reset/clear collected errors.
  8386. */
  8387. public function clearErrors(): void
  8388. {
  8389. $this->errors = [];
  8390. }
  8391. }
  8392. <?php
  8393. declare (strict_types=1);
  8394. namespace PHPUnitPHAR\PhpParser\ErrorHandler;
  8395. use PHPUnitPHAR\PhpParser\Error;
  8396. use PHPUnitPHAR\PhpParser\ErrorHandler;
  8397. /**
  8398. * Error handler that handles all errors by throwing them.
  8399. *
  8400. * This is the default strategy used by all components.
  8401. */
  8402. class Throwing implements ErrorHandler
  8403. {
  8404. public function handleError(Error $error): void
  8405. {
  8406. throw $error;
  8407. }
  8408. }
  8409. <?php
  8410. declare (strict_types=1);
  8411. namespace PHPUnitPHAR\PhpParser\Internal;
  8412. /**
  8413. * @internal
  8414. */
  8415. class DiffElem
  8416. {
  8417. public const TYPE_KEEP = 0;
  8418. public const TYPE_REMOVE = 1;
  8419. public const TYPE_ADD = 2;
  8420. public const TYPE_REPLACE = 3;
  8421. /** @var int One of the TYPE_* constants */
  8422. public int $type;
  8423. /** @var mixed Is null for add operations */
  8424. public $old;
  8425. /** @var mixed Is null for remove operations */
  8426. public $new;
  8427. /**
  8428. * @param int $type One of the TYPE_* constants
  8429. * @param mixed $old Is null for add operations
  8430. * @param mixed $new Is null for remove operations
  8431. */
  8432. public function __construct(int $type, $old, $new)
  8433. {
  8434. $this->type = $type;
  8435. $this->old = $old;
  8436. $this->new = $new;
  8437. }
  8438. }
  8439. <?php
  8440. declare (strict_types=1);
  8441. namespace PHPUnitPHAR\PhpParser\Internal;
  8442. /**
  8443. * Implements the Myers diff algorithm.
  8444. *
  8445. * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
  8446. * Algorithmica 1.1 (1986): 251-266.
  8447. *
  8448. * @template T
  8449. * @internal
  8450. */
  8451. class Differ
  8452. {
  8453. /** @var callable(T, T): bool */
  8454. private $isEqual;
  8455. /**
  8456. * Create differ over the given equality relation.
  8457. *
  8458. * @param callable(T, T): bool $isEqual Equality relation
  8459. */
  8460. public function __construct(callable $isEqual)
  8461. {
  8462. $this->isEqual = $isEqual;
  8463. }
  8464. /**
  8465. * Calculate diff (edit script) from $old to $new.
  8466. *
  8467. * @param T[] $old Original array
  8468. * @param T[] $new New array
  8469. *
  8470. * @return DiffElem[] Diff (edit script)
  8471. */
  8472. public function diff(array $old, array $new): array
  8473. {
  8474. $old = \array_values($old);
  8475. $new = \array_values($new);
  8476. list($trace, $x, $y) = $this->calculateTrace($old, $new);
  8477. return $this->extractDiff($trace, $x, $y, $old, $new);
  8478. }
  8479. /**
  8480. * Calculate diff, including "replace" operations.
  8481. *
  8482. * If a sequence of remove operations is followed by the same number of add operations, these
  8483. * will be coalesced into replace operations.
  8484. *
  8485. * @param T[] $old Original array
  8486. * @param T[] $new New array
  8487. *
  8488. * @return DiffElem[] Diff (edit script), including replace operations
  8489. */
  8490. public function diffWithReplacements(array $old, array $new): array
  8491. {
  8492. return $this->coalesceReplacements($this->diff($old, $new));
  8493. }
  8494. /**
  8495. * @param T[] $old
  8496. * @param T[] $new
  8497. * @return array{array<int, array<int, int>>, int, int}
  8498. */
  8499. private function calculateTrace(array $old, array $new): array
  8500. {
  8501. $n = \count($old);
  8502. $m = \count($new);
  8503. $max = $n + $m;
  8504. $v = [1 => 0];
  8505. $trace = [];
  8506. for ($d = 0; $d <= $max; $d++) {
  8507. $trace[] = $v;
  8508. for ($k = -$d; $k <= $d; $k += 2) {
  8509. if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
  8510. $x = $v[$k + 1];
  8511. } else {
  8512. $x = $v[$k - 1] + 1;
  8513. }
  8514. $y = $x - $k;
  8515. while ($x < $n && $y < $m && ($this->isEqual)($old[$x], $new[$y])) {
  8516. $x++;
  8517. $y++;
  8518. }
  8519. $v[$k] = $x;
  8520. if ($x >= $n && $y >= $m) {
  8521. return [$trace, $x, $y];
  8522. }
  8523. }
  8524. }
  8525. throw new \Exception('Should not happen');
  8526. }
  8527. /**
  8528. * @param array<int, array<int, int>> $trace
  8529. * @param T[] $old
  8530. * @param T[] $new
  8531. * @return DiffElem[]
  8532. */
  8533. private function extractDiff(array $trace, int $x, int $y, array $old, array $new): array
  8534. {
  8535. $result = [];
  8536. for ($d = \count($trace) - 1; $d >= 0; $d--) {
  8537. $v = $trace[$d];
  8538. $k = $x - $y;
  8539. if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
  8540. $prevK = $k + 1;
  8541. } else {
  8542. $prevK = $k - 1;
  8543. }
  8544. $prevX = $v[$prevK];
  8545. $prevY = $prevX - $prevK;
  8546. while ($x > $prevX && $y > $prevY) {
  8547. $result[] = new DiffElem(DiffElem::TYPE_KEEP, $old[$x - 1], $new[$y - 1]);
  8548. $x--;
  8549. $y--;
  8550. }
  8551. if ($d === 0) {
  8552. break;
  8553. }
  8554. while ($x > $prevX) {
  8555. $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $old[$x - 1], null);
  8556. $x--;
  8557. }
  8558. while ($y > $prevY) {
  8559. $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $new[$y - 1]);
  8560. $y--;
  8561. }
  8562. }
  8563. return array_reverse($result);
  8564. }
  8565. /**
  8566. * Coalesce equal-length sequences of remove+add into a replace operation.
  8567. *
  8568. * @param DiffElem[] $diff
  8569. * @return DiffElem[]
  8570. */
  8571. private function coalesceReplacements(array $diff): array
  8572. {
  8573. $newDiff = [];
  8574. $c = \count($diff);
  8575. for ($i = 0; $i < $c; $i++) {
  8576. $diffType = $diff[$i]->type;
  8577. if ($diffType !== DiffElem::TYPE_REMOVE) {
  8578. $newDiff[] = $diff[$i];
  8579. continue;
  8580. }
  8581. $j = $i;
  8582. while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) {
  8583. $j++;
  8584. }
  8585. $k = $j;
  8586. while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) {
  8587. $k++;
  8588. }
  8589. if ($j - $i === $k - $j) {
  8590. $len = $j - $i;
  8591. for ($n = 0; $n < $len; $n++) {
  8592. $newDiff[] = new DiffElem(DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new);
  8593. }
  8594. } else {
  8595. for (; $i < $k; $i++) {
  8596. $newDiff[] = $diff[$i];
  8597. }
  8598. }
  8599. $i = $k - 1;
  8600. }
  8601. return $newDiff;
  8602. }
  8603. }
  8604. <?php
  8605. declare (strict_types=1);
  8606. namespace PHPUnitPHAR\PhpParser\Internal;
  8607. use PHPUnitPHAR\PhpParser\Node;
  8608. use PHPUnitPHAR\PhpParser\Node\Expr;
  8609. /**
  8610. * This node is used internally by the format-preserving pretty printer to print anonymous classes.
  8611. *
  8612. * The normal anonymous class structure violates assumptions about the order of token offsets.
  8613. * Namely, the constructor arguments are part of the Expr\New_ node and follow the class node, even
  8614. * though they are actually interleaved with them. This special node type is used temporarily to
  8615. * restore a sane token offset order.
  8616. *
  8617. * @internal
  8618. */
  8619. class PrintableNewAnonClassNode extends Expr
  8620. {
  8621. /** @var Node\AttributeGroup[] PHP attribute groups */
  8622. public array $attrGroups;
  8623. /** @var int Modifiers */
  8624. public int $flags;
  8625. /** @var (Node\Arg|Node\VariadicPlaceholder)[] Arguments */
  8626. public array $args;
  8627. /** @var null|Node\Name Name of extended class */
  8628. public ?Node\Name $extends;
  8629. /** @var Node\Name[] Names of implemented interfaces */
  8630. public array $implements;
  8631. /** @var Node\Stmt[] Statements */
  8632. public array $stmts;
  8633. /**
  8634. * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
  8635. * @param (Node\Arg|Node\VariadicPlaceholder)[] $args Arguments
  8636. * @param Node\Name|null $extends Name of extended class
  8637. * @param Node\Name[] $implements Names of implemented interfaces
  8638. * @param Node\Stmt[] $stmts Statements
  8639. * @param array<string, mixed> $attributes Attributes
  8640. */
  8641. public function __construct(array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements, array $stmts, array $attributes)
  8642. {
  8643. parent::__construct($attributes);
  8644. $this->attrGroups = $attrGroups;
  8645. $this->flags = $flags;
  8646. $this->args = $args;
  8647. $this->extends = $extends;
  8648. $this->implements = $implements;
  8649. $this->stmts = $stmts;
  8650. }
  8651. public static function fromNewNode(Expr\New_ $newNode): self
  8652. {
  8653. $class = $newNode->class;
  8654. assert($class instanceof Node\Stmt\Class_);
  8655. // We don't assert that $class->name is null here, to allow consumers to assign unique names
  8656. // to anonymous classes for their own purposes. We simplify ignore the name here.
  8657. return new self($class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements, $class->stmts, $newNode->getAttributes());
  8658. }
  8659. public function getType(): string
  8660. {
  8661. return 'Expr_PrintableNewAnonClass';
  8662. }
  8663. public function getSubNodeNames(): array
  8664. {
  8665. return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts'];
  8666. }
  8667. }
  8668. <?php
  8669. declare (strict_types=1);
  8670. namespace PHPUnitPHAR\PhpParser\Internal;
  8671. if (\PHP_VERSION_ID >= 80000) {
  8672. class TokenPolyfill extends \PhpToken
  8673. {
  8674. }
  8675. return;
  8676. }
  8677. /**
  8678. * This is a polyfill for the PhpToken class introduced in PHP 8.0. We do not actually polyfill
  8679. * PhpToken, because composer might end up picking a different polyfill implementation, which does
  8680. * not meet our requirements.
  8681. *
  8682. * @internal
  8683. */
  8684. class TokenPolyfill
  8685. {
  8686. /** @var int The ID of the token. Either a T_* constant of a character code < 256. */
  8687. public int $id;
  8688. /** @var string The textual content of the token. */
  8689. public string $text;
  8690. /** @var int The 1-based starting line of the token (or -1 if unknown). */
  8691. public int $line;
  8692. /** @var int The 0-based starting position of the token (or -1 if unknown). */
  8693. public int $pos;
  8694. /** @var array<int, bool> Tokens ignored by the PHP parser. */
  8695. private const IGNORABLE_TOKENS = [\T_WHITESPACE => \true, \T_COMMENT => \true, \T_DOC_COMMENT => \true, \T_OPEN_TAG => \true];
  8696. /** @var array<int, bool> Tokens that may be part of a T_NAME_* identifier. */
  8697. private static array $identifierTokens;
  8698. /**
  8699. * Create a Token with the given ID and text, as well optional line and position information.
  8700. */
  8701. final public function __construct(int $id, string $text, int $line = -1, int $pos = -1)
  8702. {
  8703. $this->id = $id;
  8704. $this->text = $text;
  8705. $this->line = $line;
  8706. $this->pos = $pos;
  8707. }
  8708. /**
  8709. * Get the name of the token. For single-char tokens this will be the token character.
  8710. * Otherwise it will be a T_* style name, or null if the token ID is unknown.
  8711. */
  8712. public function getTokenName(): ?string
  8713. {
  8714. if ($this->id < 256) {
  8715. return \chr($this->id);
  8716. }
  8717. $name = token_name($this->id);
  8718. return $name === 'UNKNOWN' ? null : $name;
  8719. }
  8720. /**
  8721. * Check whether the token is of the given kind. The kind may be either an integer that matches
  8722. * the token ID, a string that matches the token text, or an array of integers/strings. In the
  8723. * latter case, the function returns true if any of the kinds in the array match.
  8724. *
  8725. * @param int|string|(int|string)[] $kind
  8726. */
  8727. public function is($kind): bool
  8728. {
  8729. if (\is_int($kind)) {
  8730. return $this->id === $kind;
  8731. }
  8732. if (\is_string($kind)) {
  8733. return $this->text === $kind;
  8734. }
  8735. if (\is_array($kind)) {
  8736. foreach ($kind as $entry) {
  8737. if (\is_int($entry)) {
  8738. if ($this->id === $entry) {
  8739. return \true;
  8740. }
  8741. } elseif (\is_string($entry)) {
  8742. if ($this->text === $entry) {
  8743. return \true;
  8744. }
  8745. } else {
  8746. throw new \TypeError('Argument #1 ($kind) must only have elements of type string|int, ' . gettype($entry) . ' given');
  8747. }
  8748. }
  8749. return \false;
  8750. }
  8751. throw new \TypeError('Argument #1 ($kind) must be of type string|int|array, ' . gettype($kind) . ' given');
  8752. }
  8753. /**
  8754. * Check whether this token would be ignored by the PHP parser. Returns true for T_WHITESPACE,
  8755. * T_COMMENT, T_DOC_COMMENT and T_OPEN_TAG, and false for everything else.
  8756. */
  8757. public function isIgnorable(): bool
  8758. {
  8759. return isset(self::IGNORABLE_TOKENS[$this->id]);
  8760. }
  8761. /**
  8762. * Return the textual content of the token.
  8763. */
  8764. public function __toString(): string
  8765. {
  8766. return $this->text;
  8767. }
  8768. /**
  8769. * Tokenize the given source code and return an array of tokens.
  8770. *
  8771. * This performs certain canonicalizations to match the PHP 8.0 token format:
  8772. * * Bad characters are represented using T_BAD_CHARACTER rather than omitted.
  8773. * * T_COMMENT does not include trailing newlines, instead the newline is part of a following
  8774. * T_WHITESPACE token.
  8775. * * Namespaced names are represented using T_NAME_* tokens.
  8776. *
  8777. * @return static[]
  8778. */
  8779. public static function tokenize(string $code, int $flags = 0): array
  8780. {
  8781. self::init();
  8782. $tokens = [];
  8783. $line = 1;
  8784. $pos = 0;
  8785. $origTokens = \token_get_all($code, $flags);
  8786. $numTokens = \count($origTokens);
  8787. for ($i = 0; $i < $numTokens; $i++) {
  8788. $token = $origTokens[$i];
  8789. if (\is_string($token)) {
  8790. if (\strlen($token) === 2) {
  8791. // b" and B" are tokenized as single-char tokens, even though they aren't.
  8792. $tokens[] = new static(\ord('"'), $token, $line, $pos);
  8793. $pos += 2;
  8794. } else {
  8795. $tokens[] = new static(\ord($token), $token, $line, $pos);
  8796. $pos++;
  8797. }
  8798. } else {
  8799. $id = $token[0];
  8800. $text = $token[1];
  8801. // Emulate PHP 8.0 comment format, which does not include trailing whitespace anymore.
  8802. if ($id === \T_COMMENT && \substr($text, 0, 2) !== '/*' && \preg_match('/(\r\n|\n|\r)$/D', $text, $matches)) {
  8803. $trailingNewline = $matches[0];
  8804. $text = \substr($text, 0, -\strlen($trailingNewline));
  8805. $tokens[] = new static($id, $text, $line, $pos);
  8806. $pos += \strlen($text);
  8807. if ($i + 1 < $numTokens && $origTokens[$i + 1][0] === \T_WHITESPACE) {
  8808. // Move trailing newline into following T_WHITESPACE token, if it already exists.
  8809. $origTokens[$i + 1][1] = $trailingNewline . $origTokens[$i + 1][1];
  8810. $origTokens[$i + 1][2]--;
  8811. } else {
  8812. // Otherwise, we need to create a new T_WHITESPACE token.
  8813. $tokens[] = new static(\T_WHITESPACE, $trailingNewline, $line, $pos);
  8814. $line++;
  8815. $pos += \strlen($trailingNewline);
  8816. }
  8817. continue;
  8818. }
  8819. // Emulate PHP 8.0 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and
  8820. // T_STRING into a single token.
  8821. if ($id === \T_NS_SEPARATOR || isset(self::$identifierTokens[$id])) {
  8822. $newText = $text;
  8823. $lastWasSeparator = $id === \T_NS_SEPARATOR;
  8824. for ($j = $i + 1; $j < $numTokens; $j++) {
  8825. if ($lastWasSeparator) {
  8826. if (!isset(self::$identifierTokens[$origTokens[$j][0]])) {
  8827. break;
  8828. }
  8829. $lastWasSeparator = \false;
  8830. } else {
  8831. if ($origTokens[$j][0] !== \T_NS_SEPARATOR) {
  8832. break;
  8833. }
  8834. $lastWasSeparator = \true;
  8835. }
  8836. $newText .= $origTokens[$j][1];
  8837. }
  8838. if ($lastWasSeparator) {
  8839. // Trailing separator is not part of the name.
  8840. $j--;
  8841. $newText = \substr($newText, 0, -1);
  8842. }
  8843. if ($j > $i + 1) {
  8844. if ($id === \T_NS_SEPARATOR) {
  8845. $id = \T_NAME_FULLY_QUALIFIED;
  8846. } elseif ($id === \T_NAMESPACE) {
  8847. $id = \T_NAME_RELATIVE;
  8848. } else {
  8849. $id = \T_NAME_QUALIFIED;
  8850. }
  8851. $tokens[] = new static($id, $newText, $line, $pos);
  8852. $pos += \strlen($newText);
  8853. $i = $j - 1;
  8854. continue;
  8855. }
  8856. }
  8857. $tokens[] = new static($id, $text, $line, $pos);
  8858. $line += \substr_count($text, "\n");
  8859. $pos += \strlen($text);
  8860. }
  8861. }
  8862. return $tokens;
  8863. }
  8864. /** Initialize private static state needed by tokenize(). */
  8865. private static function init(): void
  8866. {
  8867. if (isset(self::$identifierTokens)) {
  8868. return;
  8869. }
  8870. // Based on semi_reserved production.
  8871. self::$identifierTokens = \array_fill_keys([\T_STRING, \T_STATIC, \T_ABSTRACT, \T_FINAL, \T_PRIVATE, \T_PROTECTED, \T_PUBLIC, \T_READONLY, \T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND, \T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE, \T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH, \T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO, \T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT, \T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS, \T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN, \T_MATCH], \true);
  8872. }
  8873. }
  8874. <?php
  8875. declare (strict_types=1);
  8876. namespace PHPUnitPHAR\PhpParser\Internal;
  8877. use PHPUnitPHAR\PhpParser\Token;
  8878. /**
  8879. * Provides operations on token streams, for use by pretty printer.
  8880. *
  8881. * @internal
  8882. */
  8883. class TokenStream
  8884. {
  8885. /** @var Token[] Tokens (in PhpToken::tokenize() format) */
  8886. private array $tokens;
  8887. /** @var int[] Map from position to indentation */
  8888. private array $indentMap;
  8889. /**
  8890. * Create token stream instance.
  8891. *
  8892. * @param Token[] $tokens Tokens in PhpToken::tokenize() format
  8893. */
  8894. public function __construct(array $tokens, int $tabWidth)
  8895. {
  8896. $this->tokens = $tokens;
  8897. $this->indentMap = $this->calcIndentMap($tabWidth);
  8898. }
  8899. /**
  8900. * Whether the given position is immediately surrounded by parenthesis.
  8901. *
  8902. * @param int $startPos Start position
  8903. * @param int $endPos End position
  8904. */
  8905. public function haveParens(int $startPos, int $endPos): bool
  8906. {
  8907. return $this->haveTokenImmediatelyBefore($startPos, '(') && $this->haveTokenImmediatelyAfter($endPos, ')');
  8908. }
  8909. /**
  8910. * Whether the given position is immediately surrounded by braces.
  8911. *
  8912. * @param int $startPos Start position
  8913. * @param int $endPos End position
  8914. */
  8915. public function haveBraces(int $startPos, int $endPos): bool
  8916. {
  8917. return ($this->haveTokenImmediatelyBefore($startPos, '{') || $this->haveTokenImmediatelyBefore($startPos, \T_CURLY_OPEN)) && $this->haveTokenImmediatelyAfter($endPos, '}');
  8918. }
  8919. /**
  8920. * Check whether the position is directly preceded by a certain token type.
  8921. *
  8922. * During this check whitespace and comments are skipped.
  8923. *
  8924. * @param int $pos Position before which the token should occur
  8925. * @param int|string $expectedTokenType Token to check for
  8926. *
  8927. * @return bool Whether the expected token was found
  8928. */
  8929. public function haveTokenImmediatelyBefore(int $pos, $expectedTokenType): bool
  8930. {
  8931. $tokens = $this->tokens;
  8932. $pos--;
  8933. for (; $pos >= 0; $pos--) {
  8934. $token = $tokens[$pos];
  8935. if ($token->is($expectedTokenType)) {
  8936. return \true;
  8937. }
  8938. if (!$token->isIgnorable()) {
  8939. break;
  8940. }
  8941. }
  8942. return \false;
  8943. }
  8944. /**
  8945. * Check whether the position is directly followed by a certain token type.
  8946. *
  8947. * During this check whitespace and comments are skipped.
  8948. *
  8949. * @param int $pos Position after which the token should occur
  8950. * @param int|string $expectedTokenType Token to check for
  8951. *
  8952. * @return bool Whether the expected token was found
  8953. */
  8954. public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType): bool
  8955. {
  8956. $tokens = $this->tokens;
  8957. $pos++;
  8958. for ($c = \count($tokens); $pos < $c; $pos++) {
  8959. $token = $tokens[$pos];
  8960. if ($token->is($expectedTokenType)) {
  8961. return \true;
  8962. }
  8963. if (!$token->isIgnorable()) {
  8964. break;
  8965. }
  8966. }
  8967. return \false;
  8968. }
  8969. /** @param int|string|(int|string)[] $skipTokenType */
  8970. public function skipLeft(int $pos, $skipTokenType): int
  8971. {
  8972. $tokens = $this->tokens;
  8973. $pos = $this->skipLeftWhitespace($pos);
  8974. if ($skipTokenType === \T_WHITESPACE) {
  8975. return $pos;
  8976. }
  8977. if (!$tokens[$pos]->is($skipTokenType)) {
  8978. // Shouldn't happen. The skip token MUST be there
  8979. throw new \Exception('Encountered unexpected token');
  8980. }
  8981. $pos--;
  8982. return $this->skipLeftWhitespace($pos);
  8983. }
  8984. /** @param int|string|(int|string)[] $skipTokenType */
  8985. public function skipRight(int $pos, $skipTokenType): int
  8986. {
  8987. $tokens = $this->tokens;
  8988. $pos = $this->skipRightWhitespace($pos);
  8989. if ($skipTokenType === \T_WHITESPACE) {
  8990. return $pos;
  8991. }
  8992. if (!$tokens[$pos]->is($skipTokenType)) {
  8993. // Shouldn't happen. The skip token MUST be there
  8994. throw new \Exception('Encountered unexpected token');
  8995. }
  8996. $pos++;
  8997. return $this->skipRightWhitespace($pos);
  8998. }
  8999. /**
  9000. * Return first non-whitespace token position smaller or equal to passed position.
  9001. *
  9002. * @param int $pos Token position
  9003. * @return int Non-whitespace token position
  9004. */
  9005. public function skipLeftWhitespace(int $pos): int
  9006. {
  9007. $tokens = $this->tokens;
  9008. for (; $pos >= 0; $pos--) {
  9009. if (!$tokens[$pos]->isIgnorable()) {
  9010. break;
  9011. }
  9012. }
  9013. return $pos;
  9014. }
  9015. /**
  9016. * Return first non-whitespace position greater or equal to passed position.
  9017. *
  9018. * @param int $pos Token position
  9019. * @return int Non-whitespace token position
  9020. */
  9021. public function skipRightWhitespace(int $pos): int
  9022. {
  9023. $tokens = $this->tokens;
  9024. for ($count = \count($tokens); $pos < $count; $pos++) {
  9025. if (!$tokens[$pos]->isIgnorable()) {
  9026. break;
  9027. }
  9028. }
  9029. return $pos;
  9030. }
  9031. /** @param int|string|(int|string)[] $findTokenType */
  9032. public function findRight(int $pos, $findTokenType): int
  9033. {
  9034. $tokens = $this->tokens;
  9035. for ($count = \count($tokens); $pos < $count; $pos++) {
  9036. if ($tokens[$pos]->is($findTokenType)) {
  9037. return $pos;
  9038. }
  9039. }
  9040. return -1;
  9041. }
  9042. /**
  9043. * Whether the given position range contains a certain token type.
  9044. *
  9045. * @param int $startPos Starting position (inclusive)
  9046. * @param int $endPos Ending position (exclusive)
  9047. * @param int|string $tokenType Token type to look for
  9048. * @return bool Whether the token occurs in the given range
  9049. */
  9050. public function haveTokenInRange(int $startPos, int $endPos, $tokenType): bool
  9051. {
  9052. $tokens = $this->tokens;
  9053. for ($pos = $startPos; $pos < $endPos; $pos++) {
  9054. if ($tokens[$pos]->is($tokenType)) {
  9055. return \true;
  9056. }
  9057. }
  9058. return \false;
  9059. }
  9060. public function haveTagInRange(int $startPos, int $endPos): bool
  9061. {
  9062. return $this->haveTokenInRange($startPos, $endPos, \T_OPEN_TAG) || $this->haveTokenInRange($startPos, $endPos, \T_CLOSE_TAG);
  9063. }
  9064. /**
  9065. * Get indentation before token position.
  9066. *
  9067. * @param int $pos Token position
  9068. *
  9069. * @return int Indentation depth (in spaces)
  9070. */
  9071. public function getIndentationBefore(int $pos): int
  9072. {
  9073. return $this->indentMap[$pos];
  9074. }
  9075. /**
  9076. * Get the code corresponding to a token offset range, optionally adjusted for indentation.
  9077. *
  9078. * @param int $from Token start position (inclusive)
  9079. * @param int $to Token end position (exclusive)
  9080. * @param int $indent By how much the code should be indented (can be negative as well)
  9081. *
  9082. * @return string Code corresponding to token range, adjusted for indentation
  9083. */
  9084. public function getTokenCode(int $from, int $to, int $indent): string
  9085. {
  9086. $tokens = $this->tokens;
  9087. $result = '';
  9088. for ($pos = $from; $pos < $to; $pos++) {
  9089. $token = $tokens[$pos];
  9090. $id = $token->id;
  9091. $text = $token->text;
  9092. if ($id === \T_CONSTANT_ENCAPSED_STRING || $id === \T_ENCAPSED_AND_WHITESPACE) {
  9093. $result .= $text;
  9094. } else if ($indent < 0) {
  9095. $result .= str_replace("\n" . str_repeat(" ", -$indent), "\n", $text);
  9096. } elseif ($indent > 0) {
  9097. $result .= str_replace("\n", "\n" . str_repeat(" ", $indent), $text);
  9098. } else {
  9099. $result .= $text;
  9100. }
  9101. }
  9102. return $result;
  9103. }
  9104. /**
  9105. * Precalculate the indentation at every token position.
  9106. *
  9107. * @return int[] Token position to indentation map
  9108. */
  9109. private function calcIndentMap(int $tabWidth): array
  9110. {
  9111. $indentMap = [];
  9112. $indent = 0;
  9113. foreach ($this->tokens as $i => $token) {
  9114. $indentMap[] = $indent;
  9115. if ($token->id === \T_WHITESPACE) {
  9116. $content = $token->text;
  9117. $newlinePos = \strrpos($content, "\n");
  9118. if (\false !== $newlinePos) {
  9119. $indent = $this->getIndent(\substr($content, $newlinePos + 1), $tabWidth);
  9120. } elseif ($i === 1 && $this->tokens[0]->id === \T_OPEN_TAG && $this->tokens[0]->text[\strlen($this->tokens[0]->text) - 1] === "\n") {
  9121. // Special case: Newline at the end of opening tag followed by whitespace.
  9122. $indent = $this->getIndent($content, $tabWidth);
  9123. }
  9124. }
  9125. }
  9126. // Add a sentinel for one past end of the file
  9127. $indentMap[] = $indent;
  9128. return $indentMap;
  9129. }
  9130. private function getIndent(string $ws, int $tabWidth): int
  9131. {
  9132. $spaces = \substr_count($ws, " ");
  9133. $tabs = \substr_count($ws, "\t");
  9134. assert(\strlen($ws) === $spaces + $tabs);
  9135. return $spaces + $tabs * $tabWidth;
  9136. }
  9137. }
  9138. <?php
  9139. declare (strict_types=1);
  9140. namespace PHPUnitPHAR\PhpParser;
  9141. class JsonDecoder
  9142. {
  9143. /** @var \ReflectionClass<Node>[] Node type to reflection class map */
  9144. private array $reflectionClassCache;
  9145. /** @return mixed */
  9146. public function decode(string $json)
  9147. {
  9148. $value = json_decode($json, \true);
  9149. if (json_last_error()) {
  9150. throw new \RuntimeException('JSON decoding error: ' . json_last_error_msg());
  9151. }
  9152. return $this->decodeRecursive($value);
  9153. }
  9154. /**
  9155. * @param mixed $value
  9156. * @return mixed
  9157. */
  9158. private function decodeRecursive($value)
  9159. {
  9160. if (\is_array($value)) {
  9161. if (isset($value['nodeType'])) {
  9162. if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') {
  9163. return $this->decodeComment($value);
  9164. }
  9165. return $this->decodeNode($value);
  9166. }
  9167. return $this->decodeArray($value);
  9168. }
  9169. return $value;
  9170. }
  9171. private function decodeArray(array $array): array
  9172. {
  9173. $decodedArray = [];
  9174. foreach ($array as $key => $value) {
  9175. $decodedArray[$key] = $this->decodeRecursive($value);
  9176. }
  9177. return $decodedArray;
  9178. }
  9179. private function decodeNode(array $value): Node
  9180. {
  9181. $nodeType = $value['nodeType'];
  9182. if (!\is_string($nodeType)) {
  9183. throw new \RuntimeException('Node type must be a string');
  9184. }
  9185. $reflectionClass = $this->reflectionClassFromNodeType($nodeType);
  9186. $node = $reflectionClass->newInstanceWithoutConstructor();
  9187. if (isset($value['attributes'])) {
  9188. if (!\is_array($value['attributes'])) {
  9189. throw new \RuntimeException('Attributes must be an array');
  9190. }
  9191. $node->setAttributes($this->decodeArray($value['attributes']));
  9192. }
  9193. foreach ($value as $name => $subNode) {
  9194. if ($name === 'nodeType' || $name === 'attributes') {
  9195. continue;
  9196. }
  9197. $node->{$name} = $this->decodeRecursive($subNode);
  9198. }
  9199. return $node;
  9200. }
  9201. private function decodeComment(array $value): Comment
  9202. {
  9203. $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
  9204. if (!isset($value['text'])) {
  9205. throw new \RuntimeException('Comment must have text');
  9206. }
  9207. return new $className($value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1, $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1);
  9208. }
  9209. /** @return \ReflectionClass<Node> */
  9210. private function reflectionClassFromNodeType(string $nodeType): \ReflectionClass
  9211. {
  9212. if (!isset($this->reflectionClassCache[$nodeType])) {
  9213. $className = $this->classNameFromNodeType($nodeType);
  9214. $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className);
  9215. }
  9216. return $this->reflectionClassCache[$nodeType];
  9217. }
  9218. /** @return class-string<Node> */
  9219. private function classNameFromNodeType(string $nodeType): string
  9220. {
  9221. $className = 'PhpParser\Node\\' . strtr($nodeType, '_', '\\');
  9222. if (class_exists($className)) {
  9223. return $className;
  9224. }
  9225. $className .= '_';
  9226. if (class_exists($className)) {
  9227. return $className;
  9228. }
  9229. throw new \RuntimeException("Unknown node type \"{$nodeType}\"");
  9230. }
  9231. }
  9232. <?php
  9233. declare (strict_types=1);
  9234. namespace PHPUnitPHAR\PhpParser;
  9235. require __DIR__ . '/compatibility_tokens.php';
  9236. class Lexer
  9237. {
  9238. /**
  9239. * Tokenize the provided source code.
  9240. *
  9241. * The token array is in the same format as provided by the PhpToken::tokenize() method in
  9242. * PHP 8.0. The tokens are instances of PhpParser\Token, to abstract over a polyfill
  9243. * implementation in earlier PHP version.
  9244. *
  9245. * The token array is terminated by a sentinel token with token ID 0.
  9246. * The token array does not discard any tokens (i.e. whitespace and comments are included).
  9247. * The token position attributes are against this token array.
  9248. *
  9249. * @param string $code The source code to tokenize.
  9250. * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to
  9251. * ErrorHandler\Throwing.
  9252. * @return Token[] Tokens
  9253. */
  9254. public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array
  9255. {
  9256. if (null === $errorHandler) {
  9257. $errorHandler = new ErrorHandler\Throwing();
  9258. }
  9259. $scream = ini_set('xdebug.scream', '0');
  9260. $tokens = @Token::tokenize($code);
  9261. $this->postprocessTokens($tokens, $errorHandler);
  9262. if (\false !== $scream) {
  9263. ini_set('xdebug.scream', $scream);
  9264. }
  9265. return $tokens;
  9266. }
  9267. private function handleInvalidCharacter(Token $token, ErrorHandler $errorHandler): void
  9268. {
  9269. $chr = $token->text;
  9270. if ($chr === "\x00") {
  9271. // PHP cuts error message after null byte, so need special case
  9272. $errorMsg = 'Unexpected null byte';
  9273. } else {
  9274. $errorMsg = sprintf('Unexpected character "%s" (ASCII %d)', $chr, ord($chr));
  9275. }
  9276. $errorHandler->handleError(new Error($errorMsg, ['startLine' => $token->line, 'endLine' => $token->line, 'startFilePos' => $token->pos, 'endFilePos' => $token->pos]));
  9277. }
  9278. private function isUnterminatedComment(Token $token): bool
  9279. {
  9280. return $token->is([\T_COMMENT, \T_DOC_COMMENT]) && substr($token->text, 0, 2) === '/*' && substr($token->text, -2) !== '*/';
  9281. }
  9282. /**
  9283. * @param list<Token> $tokens
  9284. */
  9285. protected function postprocessTokens(array &$tokens, ErrorHandler $errorHandler): void
  9286. {
  9287. // This function reports errors (bad characters and unterminated comments) in the token
  9288. // array, and performs certain canonicalizations:
  9289. // * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and
  9290. // T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types.
  9291. // * Add a sentinel token with ID 0.
  9292. $numTokens = \count($tokens);
  9293. if ($numTokens === 0) {
  9294. // Empty input edge case: Just add the sentinel token.
  9295. $tokens[] = new Token(0, "\x00", 1, 0);
  9296. return;
  9297. }
  9298. for ($i = 0; $i < $numTokens; $i++) {
  9299. $token = $tokens[$i];
  9300. if ($token->id === \T_BAD_CHARACTER) {
  9301. $this->handleInvalidCharacter($token, $errorHandler);
  9302. }
  9303. if ($token->id === \ord('&')) {
  9304. $next = $i + 1;
  9305. while (isset($tokens[$next]) && $tokens[$next]->id === \T_WHITESPACE) {
  9306. $next++;
  9307. }
  9308. $followedByVarOrVarArg = isset($tokens[$next]) && $tokens[$next]->is([\T_VARIABLE, \T_ELLIPSIS]);
  9309. $token->id = $followedByVarOrVarArg ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
  9310. }
  9311. }
  9312. // Check for unterminated comment
  9313. $lastToken = $tokens[$numTokens - 1];
  9314. if ($this->isUnterminatedComment($lastToken)) {
  9315. $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $lastToken->line, 'endLine' => $lastToken->getEndLine(), 'startFilePos' => $lastToken->pos, 'endFilePos' => $lastToken->getEndPos()]));
  9316. }
  9317. // Add sentinel token.
  9318. $tokens[] = new Token(0, "\x00", $lastToken->getEndLine(), $lastToken->getEndPos());
  9319. }
  9320. }
  9321. <?php
  9322. declare (strict_types=1);
  9323. namespace PHPUnitPHAR\PhpParser\Lexer;
  9324. use PHPUnitPHAR\PhpParser\Error;
  9325. use PHPUnitPHAR\PhpParser\ErrorHandler;
  9326. use PHPUnitPHAR\PhpParser\Lexer;
  9327. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\AsymmetricVisibilityTokenEmulator;
  9328. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\AttributeEmulator;
  9329. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
  9330. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
  9331. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
  9332. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
  9333. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\PropertyTokenEmulator;
  9334. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
  9335. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
  9336. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReverseEmulator;
  9337. use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\TokenEmulator;
  9338. use PHPUnitPHAR\PhpParser\PhpVersion;
  9339. use PHPUnitPHAR\PhpParser\Token;
  9340. class Emulative extends Lexer
  9341. {
  9342. /** @var array{int, string, string}[] Patches used to reverse changes introduced in the code */
  9343. private array $patches = [];
  9344. /** @var list<TokenEmulator> */
  9345. private array $emulators = [];
  9346. private PhpVersion $targetPhpVersion;
  9347. private PhpVersion $hostPhpVersion;
  9348. /**
  9349. * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported.
  9350. */
  9351. public function __construct(?PhpVersion $phpVersion = null)
  9352. {
  9353. $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
  9354. $this->hostPhpVersion = PhpVersion::getHostVersion();
  9355. $emulators = [new MatchTokenEmulator(), new NullsafeTokenEmulator(), new AttributeEmulator(), new EnumTokenEmulator(), new ReadonlyTokenEmulator(), new ExplicitOctalEmulator(), new ReadonlyFunctionTokenEmulator(), new PropertyTokenEmulator(), new AsymmetricVisibilityTokenEmulator()];
  9356. // Collect emulators that are relevant for the PHP version we're running
  9357. // and the PHP version we're targeting for emulation.
  9358. foreach ($emulators as $emulator) {
  9359. $emulatorPhpVersion = $emulator->getPhpVersion();
  9360. if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
  9361. $this->emulators[] = $emulator;
  9362. } elseif ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
  9363. $this->emulators[] = new ReverseEmulator($emulator);
  9364. }
  9365. }
  9366. }
  9367. public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array
  9368. {
  9369. $emulators = array_filter($this->emulators, function ($emulator) use ($code) {
  9370. return $emulator->isEmulationNeeded($code);
  9371. });
  9372. if (empty($emulators)) {
  9373. // Nothing to emulate, yay
  9374. return parent::tokenize($code, $errorHandler);
  9375. }
  9376. if ($errorHandler === null) {
  9377. $errorHandler = new ErrorHandler\Throwing();
  9378. }
  9379. $this->patches = [];
  9380. foreach ($emulators as $emulator) {
  9381. $code = $emulator->preprocessCode($code, $this->patches);
  9382. }
  9383. $collector = new ErrorHandler\Collecting();
  9384. $tokens = parent::tokenize($code, $collector);
  9385. $this->sortPatches();
  9386. $tokens = $this->fixupTokens($tokens);
  9387. $errors = $collector->getErrors();
  9388. if (!empty($errors)) {
  9389. $this->fixupErrors($errors);
  9390. foreach ($errors as $error) {
  9391. $errorHandler->handleError($error);
  9392. }
  9393. }
  9394. foreach ($emulators as $emulator) {
  9395. $tokens = $emulator->emulate($code, $tokens);
  9396. }
  9397. return $tokens;
  9398. }
  9399. private function isForwardEmulationNeeded(PhpVersion $emulatorPhpVersion): bool
  9400. {
  9401. return $this->hostPhpVersion->older($emulatorPhpVersion) && $this->targetPhpVersion->newerOrEqual($emulatorPhpVersion);
  9402. }
  9403. private function isReverseEmulationNeeded(PhpVersion $emulatorPhpVersion): bool
  9404. {
  9405. return $this->hostPhpVersion->newerOrEqual($emulatorPhpVersion) && $this->targetPhpVersion->older($emulatorPhpVersion);
  9406. }
  9407. private function sortPatches(): void
  9408. {
  9409. // Patches may be contributed by different emulators.
  9410. // Make sure they are sorted by increasing patch position.
  9411. usort($this->patches, function ($p1, $p2) {
  9412. return $p1[0] <=> $p2[0];
  9413. });
  9414. }
  9415. /**
  9416. * @param list<Token> $tokens
  9417. * @return list<Token>
  9418. */
  9419. private function fixupTokens(array $tokens): array
  9420. {
  9421. if (\count($this->patches) === 0) {
  9422. return $tokens;
  9423. }
  9424. // Load first patch
  9425. $patchIdx = 0;
  9426. list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
  9427. // We use a manual loop over the tokens, because we modify the array on the fly
  9428. $posDelta = 0;
  9429. $lineDelta = 0;
  9430. for ($i = 0, $c = \count($tokens); $i < $c; $i++) {
  9431. $token = $tokens[$i];
  9432. $pos = $token->pos;
  9433. $token->pos += $posDelta;
  9434. $token->line += $lineDelta;
  9435. $localPosDelta = 0;
  9436. $len = \strlen($token->text);
  9437. while ($patchPos >= $pos && $patchPos < $pos + $len) {
  9438. $patchTextLen = \strlen($patchText);
  9439. if ($patchType === 'remove') {
  9440. if ($patchPos === $pos && $patchTextLen === $len) {
  9441. // Remove token entirely
  9442. array_splice($tokens, $i, 1, []);
  9443. $i--;
  9444. $c--;
  9445. } else {
  9446. // Remove from token string
  9447. $token->text = substr_replace($token->text, '', $patchPos - $pos + $localPosDelta, $patchTextLen);
  9448. $localPosDelta -= $patchTextLen;
  9449. }
  9450. $lineDelta -= \substr_count($patchText, "\n");
  9451. } elseif ($patchType === 'add') {
  9452. // Insert into the token string
  9453. $token->text = substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, 0);
  9454. $localPosDelta += $patchTextLen;
  9455. $lineDelta += \substr_count($patchText, "\n");
  9456. } elseif ($patchType === 'replace') {
  9457. // Replace inside the token string
  9458. $token->text = substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, $patchTextLen);
  9459. } else {
  9460. assert(\false);
  9461. }
  9462. // Fetch the next patch
  9463. $patchIdx++;
  9464. if ($patchIdx >= \count($this->patches)) {
  9465. // No more patches. However, we still need to adjust position.
  9466. $patchPos = \PHP_INT_MAX;
  9467. break;
  9468. }
  9469. list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
  9470. }
  9471. $posDelta += $localPosDelta;
  9472. }
  9473. return $tokens;
  9474. }
  9475. /**
  9476. * Fixup line and position information in errors.
  9477. *
  9478. * @param Error[] $errors
  9479. */
  9480. private function fixupErrors(array $errors): void
  9481. {
  9482. foreach ($errors as $error) {
  9483. $attrs = $error->getAttributes();
  9484. $posDelta = 0;
  9485. $lineDelta = 0;
  9486. foreach ($this->patches as $patch) {
  9487. list($patchPos, $patchType, $patchText) = $patch;
  9488. if ($patchPos >= $attrs['startFilePos']) {
  9489. // No longer relevant
  9490. break;
  9491. }
  9492. if ($patchType === 'add') {
  9493. $posDelta += strlen($patchText);
  9494. $lineDelta += substr_count($patchText, "\n");
  9495. } elseif ($patchType === 'remove') {
  9496. $posDelta -= strlen($patchText);
  9497. $lineDelta -= substr_count($patchText, "\n");
  9498. }
  9499. }
  9500. $attrs['startFilePos'] += $posDelta;
  9501. $attrs['endFilePos'] += $posDelta;
  9502. $attrs['startLine'] += $lineDelta;
  9503. $attrs['endLine'] += $lineDelta;
  9504. $error->setAttributes($attrs);
  9505. }
  9506. }
  9507. }
  9508. <?php
  9509. declare (strict_types=1);
  9510. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9511. use PHPUnitPHAR\PhpParser\PhpVersion;
  9512. use PHPUnitPHAR\PhpParser\Token;
  9513. final class AsymmetricVisibilityTokenEmulator extends TokenEmulator
  9514. {
  9515. public function getPhpVersion(): PhpVersion
  9516. {
  9517. return PhpVersion::fromComponents(8, 4);
  9518. }
  9519. public function isEmulationNeeded(string $code): bool
  9520. {
  9521. $code = strtolower($code);
  9522. return strpos($code, 'public(set)') !== \false || strpos($code, 'protected(set)') !== \false || strpos($code, 'private(set)') !== \false;
  9523. }
  9524. public function emulate(string $code, array $tokens): array
  9525. {
  9526. $map = [\T_PUBLIC => \T_PUBLIC_SET, \T_PROTECTED => \T_PROTECTED_SET, \T_PRIVATE => \T_PRIVATE_SET];
  9527. for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
  9528. $token = $tokens[$i];
  9529. if (isset($map[$token->id]) && $i + 3 < $c && $tokens[$i + 1]->text === '(' && $tokens[$i + 2]->id === \T_STRING && \strtolower($tokens[$i + 2]->text) === 'set' && $tokens[$i + 3]->text === ')' && $this->isKeywordContext($tokens, $i)) {
  9530. array_splice($tokens, $i, 4, [new Token($map[$token->id], $token->text . '(' . $tokens[$i + 2]->text . ')', $token->line, $token->pos)]);
  9531. $c -= 3;
  9532. }
  9533. }
  9534. return $tokens;
  9535. }
  9536. public function reverseEmulate(string $code, array $tokens): array
  9537. {
  9538. $reverseMap = [\T_PUBLIC_SET => \T_PUBLIC, \T_PROTECTED_SET => \T_PROTECTED, \T_PRIVATE_SET => \T_PRIVATE];
  9539. for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
  9540. $token = $tokens[$i];
  9541. if (isset($reverseMap[$token->id]) && \preg_match('/(public|protected|private)\((set)\)/i', $token->text, $matches)) {
  9542. [, $modifier, $set] = $matches;
  9543. $modifierLen = \strlen($modifier);
  9544. array_splice($tokens, $i, 1, [new Token($reverseMap[$token->id], $modifier, $token->line, $token->pos), new Token(\ord('('), '(', $token->line, $token->pos + $modifierLen), new Token(\T_STRING, $set, $token->line, $token->pos + $modifierLen + 1), new Token(\ord(')'), ')', $token->line, $token->pos + $modifierLen + 4)]);
  9545. $i += 3;
  9546. $c += 3;
  9547. }
  9548. }
  9549. return $tokens;
  9550. }
  9551. /** @param Token[] $tokens */
  9552. protected function isKeywordContext(array $tokens, int $pos): bool
  9553. {
  9554. $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
  9555. if ($prevToken === null) {
  9556. return \false;
  9557. }
  9558. return $prevToken->id !== \T_OBJECT_OPERATOR && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
  9559. }
  9560. /** @param Token[] $tokens */
  9561. private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token
  9562. {
  9563. for ($i = $start - 1; $i >= 0; --$i) {
  9564. if ($tokens[$i]->id === \T_WHITESPACE) {
  9565. continue;
  9566. }
  9567. return $tokens[$i];
  9568. }
  9569. return null;
  9570. }
  9571. }
  9572. <?php
  9573. declare (strict_types=1);
  9574. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9575. use PHPUnitPHAR\PhpParser\PhpVersion;
  9576. use PHPUnitPHAR\PhpParser\Token;
  9577. final class AttributeEmulator extends TokenEmulator
  9578. {
  9579. public function getPhpVersion(): PhpVersion
  9580. {
  9581. return PhpVersion::fromComponents(8, 0);
  9582. }
  9583. public function isEmulationNeeded(string $code): bool
  9584. {
  9585. return strpos($code, '#[') !== \false;
  9586. }
  9587. public function emulate(string $code, array $tokens): array
  9588. {
  9589. // We need to manually iterate and manage a count because we'll change
  9590. // the tokens array on the way.
  9591. for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
  9592. $token = $tokens[$i];
  9593. if ($token->text === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '[') {
  9594. array_splice($tokens, $i, 2, [new Token(\T_ATTRIBUTE, '#[', $token->line, $token->pos)]);
  9595. $c--;
  9596. continue;
  9597. }
  9598. }
  9599. return $tokens;
  9600. }
  9601. public function reverseEmulate(string $code, array $tokens): array
  9602. {
  9603. // TODO
  9604. return $tokens;
  9605. }
  9606. public function preprocessCode(string $code, array &$patches): string
  9607. {
  9608. $pos = 0;
  9609. while (\false !== $pos = strpos($code, '#[', $pos)) {
  9610. // Replace #[ with %[
  9611. $code[$pos] = '%';
  9612. $patches[] = [$pos, 'replace', '#'];
  9613. $pos += 2;
  9614. }
  9615. return $code;
  9616. }
  9617. }
  9618. <?php
  9619. declare (strict_types=1);
  9620. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9621. use PHPUnitPHAR\PhpParser\PhpVersion;
  9622. final class EnumTokenEmulator extends KeywordEmulator
  9623. {
  9624. public function getPhpVersion(): PhpVersion
  9625. {
  9626. return PhpVersion::fromComponents(8, 1);
  9627. }
  9628. public function getKeywordString(): string
  9629. {
  9630. return 'enum';
  9631. }
  9632. public function getKeywordToken(): int
  9633. {
  9634. return \T_ENUM;
  9635. }
  9636. protected function isKeywordContext(array $tokens, int $pos): bool
  9637. {
  9638. return parent::isKeywordContext($tokens, $pos) && isset($tokens[$pos + 2]) && $tokens[$pos + 1]->id === \T_WHITESPACE && $tokens[$pos + 2]->id === \T_STRING;
  9639. }
  9640. }
  9641. <?php
  9642. declare (strict_types=1);
  9643. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9644. use PHPUnitPHAR\PhpParser\PhpVersion;
  9645. use PHPUnitPHAR\PhpParser\Token;
  9646. class ExplicitOctalEmulator extends TokenEmulator
  9647. {
  9648. public function getPhpVersion(): PhpVersion
  9649. {
  9650. return PhpVersion::fromComponents(8, 1);
  9651. }
  9652. public function isEmulationNeeded(string $code): bool
  9653. {
  9654. return strpos($code, '0o') !== \false || strpos($code, '0O') !== \false;
  9655. }
  9656. public function emulate(string $code, array $tokens): array
  9657. {
  9658. for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
  9659. $token = $tokens[$i];
  9660. if ($token->id == \T_LNUMBER && $token->text === '0' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id == \T_STRING && preg_match('/[oO][0-7]+(?:_[0-7]+)*/', $tokens[$i + 1]->text)) {
  9661. $tokenKind = $this->resolveIntegerOrFloatToken($tokens[$i + 1]->text);
  9662. array_splice($tokens, $i, 2, [new Token($tokenKind, '0' . $tokens[$i + 1]->text, $token->line, $token->pos)]);
  9663. $c--;
  9664. }
  9665. }
  9666. return $tokens;
  9667. }
  9668. private function resolveIntegerOrFloatToken(string $str): int
  9669. {
  9670. $str = substr($str, 1);
  9671. $str = str_replace('_', '', $str);
  9672. $num = octdec($str);
  9673. return is_float($num) ? \T_DNUMBER : \T_LNUMBER;
  9674. }
  9675. public function reverseEmulate(string $code, array $tokens): array
  9676. {
  9677. // Explicit octals were not legal code previously, don't bother.
  9678. return $tokens;
  9679. }
  9680. }
  9681. <?php
  9682. declare (strict_types=1);
  9683. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9684. use PHPUnitPHAR\PhpParser\Token;
  9685. abstract class KeywordEmulator extends TokenEmulator
  9686. {
  9687. abstract public function getKeywordString(): string;
  9688. abstract public function getKeywordToken(): int;
  9689. public function isEmulationNeeded(string $code): bool
  9690. {
  9691. return strpos(strtolower($code), $this->getKeywordString()) !== \false;
  9692. }
  9693. /** @param Token[] $tokens */
  9694. protected function isKeywordContext(array $tokens, int $pos): bool
  9695. {
  9696. $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
  9697. if ($prevToken === null) {
  9698. return \false;
  9699. }
  9700. return $prevToken->id !== \T_OBJECT_OPERATOR && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
  9701. }
  9702. public function emulate(string $code, array $tokens): array
  9703. {
  9704. $keywordString = $this->getKeywordString();
  9705. foreach ($tokens as $i => $token) {
  9706. if ($token->id === \T_STRING && strtolower($token->text) === $keywordString && $this->isKeywordContext($tokens, $i)) {
  9707. $token->id = $this->getKeywordToken();
  9708. }
  9709. }
  9710. return $tokens;
  9711. }
  9712. /** @param Token[] $tokens */
  9713. private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token
  9714. {
  9715. for ($i = $start - 1; $i >= 0; --$i) {
  9716. if ($tokens[$i]->id === \T_WHITESPACE) {
  9717. continue;
  9718. }
  9719. return $tokens[$i];
  9720. }
  9721. return null;
  9722. }
  9723. public function reverseEmulate(string $code, array $tokens): array
  9724. {
  9725. $keywordToken = $this->getKeywordToken();
  9726. foreach ($tokens as $token) {
  9727. if ($token->id === $keywordToken) {
  9728. $token->id = \T_STRING;
  9729. }
  9730. }
  9731. return $tokens;
  9732. }
  9733. }
  9734. <?php
  9735. declare (strict_types=1);
  9736. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9737. use PHPUnitPHAR\PhpParser\PhpVersion;
  9738. final class MatchTokenEmulator extends KeywordEmulator
  9739. {
  9740. public function getPhpVersion(): PhpVersion
  9741. {
  9742. return PhpVersion::fromComponents(8, 0);
  9743. }
  9744. public function getKeywordString(): string
  9745. {
  9746. return 'match';
  9747. }
  9748. public function getKeywordToken(): int
  9749. {
  9750. return \T_MATCH;
  9751. }
  9752. }
  9753. <?php
  9754. declare (strict_types=1);
  9755. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9756. use PHPUnitPHAR\PhpParser\PhpVersion;
  9757. use PHPUnitPHAR\PhpParser\Token;
  9758. final class NullsafeTokenEmulator extends TokenEmulator
  9759. {
  9760. public function getPhpVersion(): PhpVersion
  9761. {
  9762. return PhpVersion::fromComponents(8, 0);
  9763. }
  9764. public function isEmulationNeeded(string $code): bool
  9765. {
  9766. return strpos($code, '?->') !== \false;
  9767. }
  9768. public function emulate(string $code, array $tokens): array
  9769. {
  9770. // We need to manually iterate and manage a count because we'll change
  9771. // the tokens array on the way
  9772. for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
  9773. $token = $tokens[$i];
  9774. if ($token->text === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id === \T_OBJECT_OPERATOR) {
  9775. array_splice($tokens, $i, 2, [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos)]);
  9776. $c--;
  9777. continue;
  9778. }
  9779. // Handle ?-> inside encapsed string.
  9780. if ($token->id === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1]) && $tokens[$i - 1]->id === \T_VARIABLE && preg_match('/^\?->([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/', $token->text, $matches)) {
  9781. $replacement = [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos), new Token(\T_STRING, $matches[1], $token->line, $token->pos + 3)];
  9782. $matchLen = \strlen($matches[0]);
  9783. if ($matchLen !== \strlen($token->text)) {
  9784. $replacement[] = new Token(\T_ENCAPSED_AND_WHITESPACE, \substr($token->text, $matchLen), $token->line, $token->pos + $matchLen);
  9785. }
  9786. array_splice($tokens, $i, 1, $replacement);
  9787. $c += \count($replacement) - 1;
  9788. continue;
  9789. }
  9790. }
  9791. return $tokens;
  9792. }
  9793. public function reverseEmulate(string $code, array $tokens): array
  9794. {
  9795. // ?-> was not valid code previously, don't bother.
  9796. return $tokens;
  9797. }
  9798. }
  9799. <?php
  9800. declare (strict_types=1);
  9801. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9802. use PHPUnitPHAR\PhpParser\PhpVersion;
  9803. final class PropertyTokenEmulator extends KeywordEmulator
  9804. {
  9805. public function getPhpVersion(): PhpVersion
  9806. {
  9807. return PhpVersion::fromComponents(8, 4);
  9808. }
  9809. public function getKeywordString(): string
  9810. {
  9811. return '__property__';
  9812. }
  9813. public function getKeywordToken(): int
  9814. {
  9815. return \T_PROPERTY_C;
  9816. }
  9817. }
  9818. <?php
  9819. declare (strict_types=1);
  9820. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9821. use PHPUnitPHAR\PhpParser\PhpVersion;
  9822. /*
  9823. * In PHP 8.1, "readonly(" was special cased in the lexer in order to support functions with
  9824. * name readonly. In PHP 8.2, this may conflict with readonly properties having a DNF type. For
  9825. * this reason, PHP 8.2 instead treats this as T_READONLY and then handles it specially in the
  9826. * parser. This emulator only exists to handle this special case, which is skipped by the
  9827. * PHP 8.1 ReadonlyTokenEmulator.
  9828. */
  9829. class ReadonlyFunctionTokenEmulator extends KeywordEmulator
  9830. {
  9831. public function getKeywordString(): string
  9832. {
  9833. return 'readonly';
  9834. }
  9835. public function getKeywordToken(): int
  9836. {
  9837. return \T_READONLY;
  9838. }
  9839. public function getPhpVersion(): PhpVersion
  9840. {
  9841. return PhpVersion::fromComponents(8, 2);
  9842. }
  9843. public function reverseEmulate(string $code, array $tokens): array
  9844. {
  9845. // Don't bother
  9846. return $tokens;
  9847. }
  9848. }
  9849. <?php
  9850. declare (strict_types=1);
  9851. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9852. use PHPUnitPHAR\PhpParser\PhpVersion;
  9853. final class ReadonlyTokenEmulator extends KeywordEmulator
  9854. {
  9855. public function getPhpVersion(): PhpVersion
  9856. {
  9857. return PhpVersion::fromComponents(8, 1);
  9858. }
  9859. public function getKeywordString(): string
  9860. {
  9861. return 'readonly';
  9862. }
  9863. public function getKeywordToken(): int
  9864. {
  9865. return \T_READONLY;
  9866. }
  9867. protected function isKeywordContext(array $tokens, int $pos): bool
  9868. {
  9869. if (!parent::isKeywordContext($tokens, $pos)) {
  9870. return \false;
  9871. }
  9872. // Support "function readonly("
  9873. return !(isset($tokens[$pos + 1]) && ($tokens[$pos + 1]->text === '(' || $tokens[$pos + 1]->id === \T_WHITESPACE && isset($tokens[$pos + 2]) && $tokens[$pos + 2]->text === '('));
  9874. }
  9875. }
  9876. <?php
  9877. declare (strict_types=1);
  9878. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9879. use PHPUnitPHAR\PhpParser\PhpVersion;
  9880. /**
  9881. * Reverses emulation direction of the inner emulator.
  9882. */
  9883. final class ReverseEmulator extends TokenEmulator
  9884. {
  9885. /** @var TokenEmulator Inner emulator */
  9886. private TokenEmulator $emulator;
  9887. public function __construct(TokenEmulator $emulator)
  9888. {
  9889. $this->emulator = $emulator;
  9890. }
  9891. public function getPhpVersion(): PhpVersion
  9892. {
  9893. return $this->emulator->getPhpVersion();
  9894. }
  9895. public function isEmulationNeeded(string $code): bool
  9896. {
  9897. return $this->emulator->isEmulationNeeded($code);
  9898. }
  9899. public function emulate(string $code, array $tokens): array
  9900. {
  9901. return $this->emulator->reverseEmulate($code, $tokens);
  9902. }
  9903. public function reverseEmulate(string $code, array $tokens): array
  9904. {
  9905. return $this->emulator->emulate($code, $tokens);
  9906. }
  9907. public function preprocessCode(string $code, array &$patches): string
  9908. {
  9909. return $code;
  9910. }
  9911. }
  9912. <?php
  9913. declare (strict_types=1);
  9914. namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
  9915. use PHPUnitPHAR\PhpParser\PhpVersion;
  9916. use PHPUnitPHAR\PhpParser\Token;
  9917. /** @internal */
  9918. abstract class TokenEmulator
  9919. {
  9920. abstract public function getPhpVersion(): PhpVersion;
  9921. abstract public function isEmulationNeeded(string $code): bool;
  9922. /**
  9923. * @param Token[] $tokens Original tokens
  9924. * @return Token[] Modified Tokens
  9925. */
  9926. abstract public function emulate(string $code, array $tokens): array;
  9927. /**
  9928. * @param Token[] $tokens Original tokens
  9929. * @return Token[] Modified Tokens
  9930. */
  9931. abstract public function reverseEmulate(string $code, array $tokens): array;
  9932. /** @param array{int, string, string}[] $patches */
  9933. public function preprocessCode(string $code, array &$patches): string
  9934. {
  9935. return $code;
  9936. }
  9937. }
  9938. <?php
  9939. declare (strict_types=1);
  9940. namespace PHPUnitPHAR\PhpParser;
  9941. /**
  9942. * Modifiers used (as a bit mask) by various flags subnodes, for example on classes, functions,
  9943. * properties and constants.
  9944. */
  9945. final class Modifiers
  9946. {
  9947. public const PUBLIC = 1;
  9948. public const PROTECTED = 2;
  9949. public const PRIVATE = 4;
  9950. public const STATIC = 8;
  9951. public const ABSTRACT = 16;
  9952. public const FINAL = 32;
  9953. public const READONLY = 64;
  9954. public const PUBLIC_SET = 128;
  9955. public const PROTECTED_SET = 256;
  9956. public const PRIVATE_SET = 512;
  9957. public const VISIBILITY_MASK = self::PUBLIC | self::PROTECTED | self::PRIVATE;
  9958. public const VISIBILITY_SET_MASK = self::PUBLIC_SET | self::PROTECTED_SET | self::PRIVATE_SET;
  9959. private const TO_STRING_MAP = [self::PUBLIC => 'public', self::PROTECTED => 'protected', self::PRIVATE => 'private', self::STATIC => 'static', self::ABSTRACT => 'abstract', self::FINAL => 'final', self::READONLY => 'readonly', self::PUBLIC_SET => 'public(set)', self::PROTECTED_SET => 'protected(set)', self::PRIVATE_SET => 'private(set)'];
  9960. public static function toString(int $modifier): string
  9961. {
  9962. if (!isset(self::TO_STRING_MAP[$modifier])) {
  9963. throw new \InvalidArgumentException("Unknown modifier {$modifier}");
  9964. }
  9965. return self::TO_STRING_MAP[$modifier];
  9966. }
  9967. private static function isValidModifier(int $modifier): bool
  9968. {
  9969. $isPow2 = ($modifier & $modifier - 1) == 0 && $modifier != 0;
  9970. return $isPow2 && $modifier <= self::PRIVATE_SET;
  9971. }
  9972. /**
  9973. * @internal
  9974. */
  9975. public static function verifyClassModifier(int $a, int $b): void
  9976. {
  9977. assert(self::isValidModifier($b));
  9978. if (($a & $b) != 0) {
  9979. throw new Error('Multiple ' . self::toString($b) . ' modifiers are not allowed');
  9980. }
  9981. if ($a & 48 && $b & 48) {
  9982. throw new Error('Cannot use the final modifier on an abstract class');
  9983. }
  9984. }
  9985. /**
  9986. * @internal
  9987. */
  9988. public static function verifyModifier(int $a, int $b): void
  9989. {
  9990. assert(self::isValidModifier($b));
  9991. if ($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK || $a & Modifiers::VISIBILITY_SET_MASK && $b & Modifiers::VISIBILITY_SET_MASK) {
  9992. throw new Error('Multiple access type modifiers are not allowed');
  9993. }
  9994. if (($a & $b) != 0) {
  9995. throw new Error('Multiple ' . self::toString($b) . ' modifiers are not allowed');
  9996. }
  9997. if ($a & 48 && $b & 48) {
  9998. throw new Error('Cannot use the final modifier on an abstract class member');
  9999. }
  10000. }
  10001. }
  10002. <?php
  10003. declare (strict_types=1);
  10004. namespace PHPUnitPHAR\PhpParser;
  10005. use PHPUnitPHAR\PhpParser\Node\Name;
  10006. use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
  10007. use PHPUnitPHAR\PhpParser\Node\Stmt;
  10008. class NameContext
  10009. {
  10010. /** @var null|Name Current namespace */
  10011. protected ?Name $namespace;
  10012. /** @var Name[][] Map of format [aliasType => [aliasName => originalName]] */
  10013. protected array $aliases = [];
  10014. /** @var Name[][] Same as $aliases but preserving original case */
  10015. protected array $origAliases = [];
  10016. /** @var ErrorHandler Error handler */
  10017. protected ErrorHandler $errorHandler;
  10018. /**
  10019. * Create a name context.
  10020. *
  10021. * @param ErrorHandler $errorHandler Error handling used to report errors
  10022. */
  10023. public function __construct(ErrorHandler $errorHandler)
  10024. {
  10025. $this->errorHandler = $errorHandler;
  10026. }
  10027. /**
  10028. * Start a new namespace.
  10029. *
  10030. * This also resets the alias table.
  10031. *
  10032. * @param Name|null $namespace Null is the global namespace
  10033. */
  10034. public function startNamespace(?Name $namespace = null): void
  10035. {
  10036. $this->namespace = $namespace;
  10037. $this->origAliases = $this->aliases = [Stmt\Use_::TYPE_NORMAL => [], Stmt\Use_::TYPE_FUNCTION => [], Stmt\Use_::TYPE_CONSTANT => []];
  10038. }
  10039. /**
  10040. * Add an alias / import.
  10041. *
  10042. * @param Name $name Original name
  10043. * @param string $aliasName Aliased name
  10044. * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
  10045. * @param array<string, mixed> $errorAttrs Attributes to use to report an error
  10046. */
  10047. public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []): void
  10048. {
  10049. // Constant names are case sensitive, everything else case insensitive
  10050. if ($type === Stmt\Use_::TYPE_CONSTANT) {
  10051. $aliasLookupName = $aliasName;
  10052. } else {
  10053. $aliasLookupName = strtolower($aliasName);
  10054. }
  10055. if (isset($this->aliases[$type][$aliasLookupName])) {
  10056. $typeStringMap = [Stmt\Use_::TYPE_NORMAL => '', Stmt\Use_::TYPE_FUNCTION => 'function ', Stmt\Use_::TYPE_CONSTANT => 'const '];
  10057. $this->errorHandler->handleError(new Error(sprintf('Cannot use %s%s as %s because the name is already in use', $typeStringMap[$type], $name, $aliasName), $errorAttrs));
  10058. return;
  10059. }
  10060. $this->aliases[$type][$aliasLookupName] = $name;
  10061. $this->origAliases[$type][$aliasName] = $name;
  10062. }
  10063. /**
  10064. * Get current namespace.
  10065. *
  10066. * @return null|Name Namespace (or null if global namespace)
  10067. */
  10068. public function getNamespace(): ?Name
  10069. {
  10070. return $this->namespace;
  10071. }
  10072. /**
  10073. * Get resolved name.
  10074. *
  10075. * @param Name $name Name to resolve
  10076. * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT}
  10077. *
  10078. * @return null|Name Resolved name, or null if static resolution is not possible
  10079. */
  10080. public function getResolvedName(Name $name, int $type): ?Name
  10081. {
  10082. // don't resolve special class names
  10083. if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) {
  10084. if (!$name->isUnqualified()) {
  10085. $this->errorHandler->handleError(new Error(sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getAttributes()));
  10086. }
  10087. return $name;
  10088. }
  10089. // fully qualified names are already resolved
  10090. if ($name->isFullyQualified()) {
  10091. return $name;
  10092. }
  10093. // Try to resolve aliases
  10094. if (null !== $resolvedName = $this->resolveAlias($name, $type)) {
  10095. return $resolvedName;
  10096. }
  10097. if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) {
  10098. if (null === $this->namespace) {
  10099. // outside of a namespace unaliased unqualified is same as fully qualified
  10100. return new FullyQualified($name, $name->getAttributes());
  10101. }
  10102. // Cannot resolve statically
  10103. return null;
  10104. }
  10105. // if no alias exists prepend current namespace
  10106. return FullyQualified::concat($this->namespace, $name, $name->getAttributes());
  10107. }
  10108. /**
  10109. * Get resolved class name.
  10110. *
  10111. * @param Name $name Class ame to resolve
  10112. *
  10113. * @return Name Resolved name
  10114. */
  10115. public function getResolvedClassName(Name $name): Name
  10116. {
  10117. return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL);
  10118. }
  10119. /**
  10120. * Get possible ways of writing a fully qualified name (e.g., by making use of aliases).
  10121. *
  10122. * @param string $name Fully-qualified name (without leading namespace separator)
  10123. * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
  10124. *
  10125. * @return Name[] Possible representations of the name
  10126. */
  10127. public function getPossibleNames(string $name, int $type): array
  10128. {
  10129. $lcName = strtolower($name);
  10130. if ($type === Stmt\Use_::TYPE_NORMAL) {
  10131. // self, parent and static must always be unqualified
  10132. if ($lcName === "self" || $lcName === "parent" || $lcName === "static") {
  10133. return [new Name($name)];
  10134. }
  10135. }
  10136. // Collect possible ways to write this name, starting with the fully-qualified name
  10137. $possibleNames = [new FullyQualified($name)];
  10138. if (null !== $nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type)) {
  10139. // Make sure there is no alias that makes the normally namespace-relative name
  10140. // into something else
  10141. if (null === $this->resolveAlias($nsRelativeName, $type)) {
  10142. $possibleNames[] = $nsRelativeName;
  10143. }
  10144. }
  10145. // Check for relevant namespace use statements
  10146. foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) {
  10147. $lcOrig = $orig->toLowerString();
  10148. if (0 === strpos($lcName, $lcOrig . '\\')) {
  10149. $possibleNames[] = new Name($alias . substr($name, strlen($lcOrig)));
  10150. }
  10151. }
  10152. // Check for relevant type-specific use statements
  10153. foreach ($this->origAliases[$type] as $alias => $orig) {
  10154. if ($type === Stmt\Use_::TYPE_CONSTANT) {
  10155. // Constants are complicated-sensitive
  10156. $normalizedOrig = $this->normalizeConstName($orig->toString());
  10157. if ($normalizedOrig === $this->normalizeConstName($name)) {
  10158. $possibleNames[] = new Name($alias);
  10159. }
  10160. } else if ($orig->toLowerString() === $lcName) {
  10161. $possibleNames[] = new Name($alias);
  10162. }
  10163. }
  10164. return $possibleNames;
  10165. }
  10166. /**
  10167. * Get shortest representation of this fully-qualified name.
  10168. *
  10169. * @param string $name Fully-qualified name (without leading namespace separator)
  10170. * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
  10171. *
  10172. * @return Name Shortest representation
  10173. */
  10174. public function getShortName(string $name, int $type): Name
  10175. {
  10176. $possibleNames = $this->getPossibleNames($name, $type);
  10177. // Find shortest name
  10178. $shortestName = null;
  10179. $shortestLength = \INF;
  10180. foreach ($possibleNames as $possibleName) {
  10181. $length = strlen($possibleName->toCodeString());
  10182. if ($length < $shortestLength) {
  10183. $shortestName = $possibleName;
  10184. $shortestLength = $length;
  10185. }
  10186. }
  10187. return $shortestName;
  10188. }
  10189. private function resolveAlias(Name $name, int $type): ?FullyQualified
  10190. {
  10191. $firstPart = $name->getFirst();
  10192. if ($name->isQualified()) {
  10193. // resolve aliases for qualified names, always against class alias table
  10194. $checkName = strtolower($firstPart);
  10195. if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) {
  10196. $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName];
  10197. return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes());
  10198. }
  10199. } elseif ($name->isUnqualified()) {
  10200. // constant aliases are case-sensitive, function aliases case-insensitive
  10201. $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : strtolower($firstPart);
  10202. if (isset($this->aliases[$type][$checkName])) {
  10203. // resolve unqualified aliases
  10204. return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes());
  10205. }
  10206. }
  10207. // No applicable aliases
  10208. return null;
  10209. }
  10210. private function getNamespaceRelativeName(string $name, string $lcName, int $type): ?Name
  10211. {
  10212. if (null === $this->namespace) {
  10213. return new Name($name);
  10214. }
  10215. if ($type === Stmt\Use_::TYPE_CONSTANT) {
  10216. // The constants true/false/null always resolve to the global symbols, even inside a
  10217. // namespace, so they may be used without qualification
  10218. if ($lcName === "true" || $lcName === "false" || $lcName === "null") {
  10219. return new Name($name);
  10220. }
  10221. }
  10222. $namespacePrefix = strtolower($this->namespace . '\\');
  10223. if (0 === strpos($lcName, $namespacePrefix)) {
  10224. return new Name(substr($name, strlen($namespacePrefix)));
  10225. }
  10226. return null;
  10227. }
  10228. private function normalizeConstName(string $name): string
  10229. {
  10230. $nsSep = strrpos($name, '\\');
  10231. if (\false === $nsSep) {
  10232. return $name;
  10233. }
  10234. // Constants have case-insensitive namespace and case-sensitive short-name
  10235. $ns = substr($name, 0, $nsSep);
  10236. $shortName = substr($name, $nsSep + 1);
  10237. return strtolower($ns) . '\\' . $shortName;
  10238. }
  10239. }
  10240. <?php
  10241. declare (strict_types=1);
  10242. namespace PHPUnitPHAR\PhpParser;
  10243. interface Node
  10244. {
  10245. /**
  10246. * Gets the type of the node.
  10247. *
  10248. * @psalm-return non-empty-string
  10249. * @return string Type of the node
  10250. */
  10251. public function getType(): string;
  10252. /**
  10253. * Gets the names of the sub nodes.
  10254. *
  10255. * @return string[] Names of sub nodes
  10256. */
  10257. public function getSubNodeNames(): array;
  10258. /**
  10259. * Gets line the node started in (alias of getStartLine).
  10260. *
  10261. * @return int Start line (or -1 if not available)
  10262. * @phpstan-return -1|positive-int
  10263. *
  10264. * @deprecated Use getStartLine() instead
  10265. */
  10266. public function getLine(): int;
  10267. /**
  10268. * Gets line the node started in.
  10269. *
  10270. * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
  10271. *
  10272. * @return int Start line (or -1 if not available)
  10273. * @phpstan-return -1|positive-int
  10274. */
  10275. public function getStartLine(): int;
  10276. /**
  10277. * Gets the line the node ended in.
  10278. *
  10279. * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
  10280. *
  10281. * @return int End line (or -1 if not available)
  10282. * @phpstan-return -1|positive-int
  10283. */
  10284. public function getEndLine(): int;
  10285. /**
  10286. * Gets the token offset of the first token that is part of this node.
  10287. *
  10288. * The offset is an index into the array returned by Lexer::getTokens().
  10289. *
  10290. * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  10291. *
  10292. * @return int Token start position (or -1 if not available)
  10293. */
  10294. public function getStartTokenPos(): int;
  10295. /**
  10296. * Gets the token offset of the last token that is part of this node.
  10297. *
  10298. * The offset is an index into the array returned by Lexer::getTokens().
  10299. *
  10300. * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  10301. *
  10302. * @return int Token end position (or -1 if not available)
  10303. */
  10304. public function getEndTokenPos(): int;
  10305. /**
  10306. * Gets the file offset of the first character that is part of this node.
  10307. *
  10308. * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
  10309. *
  10310. * @return int File start position (or -1 if not available)
  10311. */
  10312. public function getStartFilePos(): int;
  10313. /**
  10314. * Gets the file offset of the last character that is part of this node.
  10315. *
  10316. * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
  10317. *
  10318. * @return int File end position (or -1 if not available)
  10319. */
  10320. public function getEndFilePos(): int;
  10321. /**
  10322. * Gets all comments directly preceding this node.
  10323. *
  10324. * The comments are also available through the "comments" attribute.
  10325. *
  10326. * @return Comment[]
  10327. */
  10328. public function getComments(): array;
  10329. /**
  10330. * Gets the doc comment of the node.
  10331. *
  10332. * @return null|Comment\Doc Doc comment object or null
  10333. */
  10334. public function getDocComment(): ?Comment\Doc;
  10335. /**
  10336. * Sets the doc comment of the node.
  10337. *
  10338. * This will either replace an existing doc comment or add it to the comments array.
  10339. *
  10340. * @param Comment\Doc $docComment Doc comment to set
  10341. */
  10342. public function setDocComment(Comment\Doc $docComment): void;
  10343. /**
  10344. * Sets an attribute on a node.
  10345. *
  10346. * @param mixed $value
  10347. */
  10348. public function setAttribute(string $key, $value): void;
  10349. /**
  10350. * Returns whether an attribute exists.
  10351. */
  10352. public function hasAttribute(string $key): bool;
  10353. /**
  10354. * Returns the value of an attribute.
  10355. *
  10356. * @param mixed $default
  10357. *
  10358. * @return mixed
  10359. */
  10360. public function getAttribute(string $key, $default = null);
  10361. /**
  10362. * Returns all the attributes of this node.
  10363. *
  10364. * @return array<string, mixed>
  10365. */
  10366. public function getAttributes(): array;
  10367. /**
  10368. * Replaces all the attributes of this node.
  10369. *
  10370. * @param array<string, mixed> $attributes
  10371. */
  10372. public function setAttributes(array $attributes): void;
  10373. }
  10374. <?php
  10375. declare (strict_types=1);
  10376. namespace PHPUnitPHAR\PhpParser\Node;
  10377. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10378. class Arg extends NodeAbstract
  10379. {
  10380. /** @var Identifier|null Parameter name (for named parameters) */
  10381. public ?Identifier $name;
  10382. /** @var Expr Value to pass */
  10383. public Expr $value;
  10384. /** @var bool Whether to pass by ref */
  10385. public bool $byRef;
  10386. /** @var bool Whether to unpack the argument */
  10387. public bool $unpack;
  10388. /**
  10389. * Constructs a function call argument node.
  10390. *
  10391. * @param Expr $value Value to pass
  10392. * @param bool $byRef Whether to pass by ref
  10393. * @param bool $unpack Whether to unpack the argument
  10394. * @param array<string, mixed> $attributes Additional attributes
  10395. * @param Identifier|null $name Parameter name (for named parameters)
  10396. */
  10397. public function __construct(Expr $value, bool $byRef = \false, bool $unpack = \false, array $attributes = [], ?Identifier $name = null)
  10398. {
  10399. $this->attributes = $attributes;
  10400. $this->name = $name;
  10401. $this->value = $value;
  10402. $this->byRef = $byRef;
  10403. $this->unpack = $unpack;
  10404. }
  10405. public function getSubNodeNames(): array
  10406. {
  10407. return ['name', 'value', 'byRef', 'unpack'];
  10408. }
  10409. public function getType(): string
  10410. {
  10411. return 'Arg';
  10412. }
  10413. }
  10414. <?php
  10415. declare (strict_types=1);
  10416. namespace PHPUnitPHAR\PhpParser\Node;
  10417. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10418. class ArrayItem extends NodeAbstract
  10419. {
  10420. /** @var null|Expr Key */
  10421. public ?Expr $key;
  10422. /** @var Expr Value */
  10423. public Expr $value;
  10424. /** @var bool Whether to assign by reference */
  10425. public bool $byRef;
  10426. /** @var bool Whether to unpack the argument */
  10427. public bool $unpack;
  10428. /**
  10429. * Constructs an array item node.
  10430. *
  10431. * @param Expr $value Value
  10432. * @param null|Expr $key Key
  10433. * @param bool $byRef Whether to assign by reference
  10434. * @param array<string, mixed> $attributes Additional attributes
  10435. */
  10436. public function __construct(Expr $value, ?Expr $key = null, bool $byRef = \false, array $attributes = [], bool $unpack = \false)
  10437. {
  10438. $this->attributes = $attributes;
  10439. $this->key = $key;
  10440. $this->value = $value;
  10441. $this->byRef = $byRef;
  10442. $this->unpack = $unpack;
  10443. }
  10444. public function getSubNodeNames(): array
  10445. {
  10446. return ['key', 'value', 'byRef', 'unpack'];
  10447. }
  10448. public function getType(): string
  10449. {
  10450. return 'ArrayItem';
  10451. }
  10452. }
  10453. // @deprecated compatibility alias
  10454. class_alias(ArrayItem::class, Expr\ArrayItem::class);
  10455. <?php
  10456. declare (strict_types=1);
  10457. namespace PHPUnitPHAR\PhpParser\Node;
  10458. use PHPUnitPHAR\PhpParser\Node;
  10459. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10460. class Attribute extends NodeAbstract
  10461. {
  10462. /** @var Name Attribute name */
  10463. public Name $name;
  10464. /** @var list<Arg> Attribute arguments */
  10465. public array $args;
  10466. /**
  10467. * @param Node\Name $name Attribute name
  10468. * @param list<Arg> $args Attribute arguments
  10469. * @param array<string, mixed> $attributes Additional node attributes
  10470. */
  10471. public function __construct(Name $name, array $args = [], array $attributes = [])
  10472. {
  10473. $this->attributes = $attributes;
  10474. $this->name = $name;
  10475. $this->args = $args;
  10476. }
  10477. public function getSubNodeNames(): array
  10478. {
  10479. return ['name', 'args'];
  10480. }
  10481. public function getType(): string
  10482. {
  10483. return 'Attribute';
  10484. }
  10485. }
  10486. <?php
  10487. declare (strict_types=1);
  10488. namespace PHPUnitPHAR\PhpParser\Node;
  10489. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10490. class AttributeGroup extends NodeAbstract
  10491. {
  10492. /** @var Attribute[] Attributes */
  10493. public array $attrs;
  10494. /**
  10495. * @param Attribute[] $attrs PHP attributes
  10496. * @param array<string, mixed> $attributes Additional node attributes
  10497. */
  10498. public function __construct(array $attrs, array $attributes = [])
  10499. {
  10500. $this->attributes = $attributes;
  10501. $this->attrs = $attrs;
  10502. }
  10503. public function getSubNodeNames(): array
  10504. {
  10505. return ['attrs'];
  10506. }
  10507. public function getType(): string
  10508. {
  10509. return 'AttributeGroup';
  10510. }
  10511. }
  10512. <?php
  10513. declare (strict_types=1);
  10514. namespace PHPUnitPHAR\PhpParser\Node;
  10515. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10516. class ClosureUse extends NodeAbstract
  10517. {
  10518. /** @var Expr\Variable Variable to use */
  10519. public Expr\Variable $var;
  10520. /** @var bool Whether to use by reference */
  10521. public bool $byRef;
  10522. /**
  10523. * Constructs a closure use node.
  10524. *
  10525. * @param Expr\Variable $var Variable to use
  10526. * @param bool $byRef Whether to use by reference
  10527. * @param array<string, mixed> $attributes Additional attributes
  10528. */
  10529. public function __construct(Expr\Variable $var, bool $byRef = \false, array $attributes = [])
  10530. {
  10531. $this->attributes = $attributes;
  10532. $this->var = $var;
  10533. $this->byRef = $byRef;
  10534. }
  10535. public function getSubNodeNames(): array
  10536. {
  10537. return ['var', 'byRef'];
  10538. }
  10539. public function getType(): string
  10540. {
  10541. return 'ClosureUse';
  10542. }
  10543. }
  10544. // @deprecated compatibility alias
  10545. class_alias(ClosureUse::class, Expr\ClosureUse::class);
  10546. <?php
  10547. declare (strict_types=1);
  10548. namespace PHPUnitPHAR\PhpParser\Node;
  10549. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10550. /**
  10551. * This is a base class for complex types, including nullable types and union types.
  10552. *
  10553. * It does not provide any shared behavior and exists only for type-checking purposes.
  10554. */
  10555. abstract class ComplexType extends NodeAbstract
  10556. {
  10557. }
  10558. <?php
  10559. declare (strict_types=1);
  10560. namespace PHPUnitPHAR\PhpParser\Node;
  10561. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10562. class Const_ extends NodeAbstract
  10563. {
  10564. /** @var Identifier Name */
  10565. public Identifier $name;
  10566. /** @var Expr Value */
  10567. public Expr $value;
  10568. /** @var Name|null Namespaced name (if using NameResolver) */
  10569. public ?Name $namespacedName;
  10570. /**
  10571. * Constructs a const node for use in class const and const statements.
  10572. *
  10573. * @param string|Identifier $name Name
  10574. * @param Expr $value Value
  10575. * @param array<string, mixed> $attributes Additional attributes
  10576. */
  10577. public function __construct($name, Expr $value, array $attributes = [])
  10578. {
  10579. $this->attributes = $attributes;
  10580. $this->name = \is_string($name) ? new Identifier($name) : $name;
  10581. $this->value = $value;
  10582. }
  10583. public function getSubNodeNames(): array
  10584. {
  10585. return ['name', 'value'];
  10586. }
  10587. public function getType(): string
  10588. {
  10589. return 'Const';
  10590. }
  10591. }
  10592. <?php
  10593. declare (strict_types=1);
  10594. namespace PHPUnitPHAR\PhpParser\Node;
  10595. use PHPUnitPHAR\PhpParser\Node;
  10596. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10597. class DeclareItem extends NodeAbstract
  10598. {
  10599. /** @var Node\Identifier Key */
  10600. public Identifier $key;
  10601. /** @var Node\Expr Value */
  10602. public Expr $value;
  10603. /**
  10604. * Constructs a declare key=>value pair node.
  10605. *
  10606. * @param string|Node\Identifier $key Key
  10607. * @param Node\Expr $value Value
  10608. * @param array<string, mixed> $attributes Additional attributes
  10609. */
  10610. public function __construct($key, Node\Expr $value, array $attributes = [])
  10611. {
  10612. $this->attributes = $attributes;
  10613. $this->key = \is_string($key) ? new Node\Identifier($key) : $key;
  10614. $this->value = $value;
  10615. }
  10616. public function getSubNodeNames(): array
  10617. {
  10618. return ['key', 'value'];
  10619. }
  10620. public function getType(): string
  10621. {
  10622. return 'DeclareItem';
  10623. }
  10624. }
  10625. // @deprecated compatibility alias
  10626. class_alias(DeclareItem::class, Stmt\DeclareDeclare::class);
  10627. <?php
  10628. declare (strict_types=1);
  10629. namespace PHPUnitPHAR\PhpParser\Node;
  10630. use PHPUnitPHAR\PhpParser\NodeAbstract;
  10631. abstract class Expr extends NodeAbstract
  10632. {
  10633. }
  10634. <?php
  10635. declare (strict_types=1);
  10636. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10637. use PHPUnitPHAR\PhpParser\Node\Expr;
  10638. class ArrayDimFetch extends Expr
  10639. {
  10640. /** @var Expr Variable */
  10641. public Expr $var;
  10642. /** @var null|Expr Array index / dim */
  10643. public ?Expr $dim;
  10644. /**
  10645. * Constructs an array index fetch node.
  10646. *
  10647. * @param Expr $var Variable
  10648. * @param null|Expr $dim Array index / dim
  10649. * @param array<string, mixed> $attributes Additional attributes
  10650. */
  10651. public function __construct(Expr $var, ?Expr $dim = null, array $attributes = [])
  10652. {
  10653. $this->attributes = $attributes;
  10654. $this->var = $var;
  10655. $this->dim = $dim;
  10656. }
  10657. public function getSubNodeNames(): array
  10658. {
  10659. return ['var', 'dim'];
  10660. }
  10661. public function getType(): string
  10662. {
  10663. return 'Expr_ArrayDimFetch';
  10664. }
  10665. }
  10666. <?php
  10667. declare (strict_types=1);
  10668. namespace PHPUnitPHAR;
  10669. require __DIR__ . '/../ArrayItem.php';
  10670. <?php
  10671. declare (strict_types=1);
  10672. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10673. use PHPUnitPHAR\PhpParser\Node\ArrayItem;
  10674. use PHPUnitPHAR\PhpParser\Node\Expr;
  10675. class Array_ extends Expr
  10676. {
  10677. // For use in "kind" attribute
  10678. public const KIND_LONG = 1;
  10679. // array() syntax
  10680. public const KIND_SHORT = 2;
  10681. // [] syntax
  10682. /** @var ArrayItem[] Items */
  10683. public array $items;
  10684. /**
  10685. * Constructs an array node.
  10686. *
  10687. * @param ArrayItem[] $items Items of the array
  10688. * @param array<string, mixed> $attributes Additional attributes
  10689. */
  10690. public function __construct(array $items = [], array $attributes = [])
  10691. {
  10692. $this->attributes = $attributes;
  10693. $this->items = $items;
  10694. }
  10695. public function getSubNodeNames(): array
  10696. {
  10697. return ['items'];
  10698. }
  10699. public function getType(): string
  10700. {
  10701. return 'Expr_Array';
  10702. }
  10703. }
  10704. <?php
  10705. declare (strict_types=1);
  10706. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10707. use PHPUnitPHAR\PhpParser\Node;
  10708. use PHPUnitPHAR\PhpParser\Node\Expr;
  10709. use PHPUnitPHAR\PhpParser\Node\FunctionLike;
  10710. class ArrowFunction extends Expr implements FunctionLike
  10711. {
  10712. /** @var bool Whether the closure is static */
  10713. public bool $static;
  10714. /** @var bool Whether to return by reference */
  10715. public bool $byRef;
  10716. /** @var Node\Param[] */
  10717. public array $params = [];
  10718. /** @var null|Node\Identifier|Node\Name|Node\ComplexType */
  10719. public ?Node $returnType;
  10720. /** @var Expr Expression body */
  10721. public Expr $expr;
  10722. /** @var Node\AttributeGroup[] */
  10723. public array $attrGroups;
  10724. /**
  10725. * @param array{
  10726. * expr: Expr,
  10727. * static?: bool,
  10728. * byRef?: bool,
  10729. * params?: Node\Param[],
  10730. * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
  10731. * attrGroups?: Node\AttributeGroup[]
  10732. * } $subNodes Array of the following subnodes:
  10733. * 'expr' : Expression body
  10734. * 'static' => false : Whether the closure is static
  10735. * 'byRef' => false : Whether to return by reference
  10736. * 'params' => array() : Parameters
  10737. * 'returnType' => null : Return type
  10738. * 'attrGroups' => array() : PHP attribute groups
  10739. * @param array<string, mixed> $attributes Additional attributes
  10740. */
  10741. public function __construct(array $subNodes, array $attributes = [])
  10742. {
  10743. $this->attributes = $attributes;
  10744. $this->static = $subNodes['static'] ?? \false;
  10745. $this->byRef = $subNodes['byRef'] ?? \false;
  10746. $this->params = $subNodes['params'] ?? [];
  10747. $this->returnType = $subNodes['returnType'] ?? null;
  10748. $this->expr = $subNodes['expr'];
  10749. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  10750. }
  10751. public function getSubNodeNames(): array
  10752. {
  10753. return ['attrGroups', 'static', 'byRef', 'params', 'returnType', 'expr'];
  10754. }
  10755. public function returnsByRef(): bool
  10756. {
  10757. return $this->byRef;
  10758. }
  10759. public function getParams(): array
  10760. {
  10761. return $this->params;
  10762. }
  10763. public function getReturnType()
  10764. {
  10765. return $this->returnType;
  10766. }
  10767. public function getAttrGroups(): array
  10768. {
  10769. return $this->attrGroups;
  10770. }
  10771. /**
  10772. * @return Node\Stmt\Return_[]
  10773. */
  10774. public function getStmts(): array
  10775. {
  10776. return [new Node\Stmt\Return_($this->expr)];
  10777. }
  10778. public function getType(): string
  10779. {
  10780. return 'Expr_ArrowFunction';
  10781. }
  10782. }
  10783. <?php
  10784. declare (strict_types=1);
  10785. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10786. use PHPUnitPHAR\PhpParser\Node\Expr;
  10787. class Assign extends Expr
  10788. {
  10789. /** @var Expr Variable */
  10790. public Expr $var;
  10791. /** @var Expr Expression */
  10792. public Expr $expr;
  10793. /**
  10794. * Constructs an assignment node.
  10795. *
  10796. * @param Expr $var Variable
  10797. * @param Expr $expr Expression
  10798. * @param array<string, mixed> $attributes Additional attributes
  10799. */
  10800. public function __construct(Expr $var, Expr $expr, array $attributes = [])
  10801. {
  10802. $this->attributes = $attributes;
  10803. $this->var = $var;
  10804. $this->expr = $expr;
  10805. }
  10806. public function getSubNodeNames(): array
  10807. {
  10808. return ['var', 'expr'];
  10809. }
  10810. public function getType(): string
  10811. {
  10812. return 'Expr_Assign';
  10813. }
  10814. }
  10815. <?php
  10816. declare (strict_types=1);
  10817. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10818. use PHPUnitPHAR\PhpParser\Node\Expr;
  10819. abstract class AssignOp extends Expr
  10820. {
  10821. /** @var Expr Variable */
  10822. public Expr $var;
  10823. /** @var Expr Expression */
  10824. public Expr $expr;
  10825. /**
  10826. * Constructs a compound assignment operation node.
  10827. *
  10828. * @param Expr $var Variable
  10829. * @param Expr $expr Expression
  10830. * @param array<string, mixed> $attributes Additional attributes
  10831. */
  10832. public function __construct(Expr $var, Expr $expr, array $attributes = [])
  10833. {
  10834. $this->attributes = $attributes;
  10835. $this->var = $var;
  10836. $this->expr = $expr;
  10837. }
  10838. public function getSubNodeNames(): array
  10839. {
  10840. return ['var', 'expr'];
  10841. }
  10842. }
  10843. <?php
  10844. declare (strict_types=1);
  10845. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10846. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10847. class BitwiseAnd extends AssignOp
  10848. {
  10849. public function getType(): string
  10850. {
  10851. return 'Expr_AssignOp_BitwiseAnd';
  10852. }
  10853. }
  10854. <?php
  10855. declare (strict_types=1);
  10856. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10857. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10858. class BitwiseOr extends AssignOp
  10859. {
  10860. public function getType(): string
  10861. {
  10862. return 'Expr_AssignOp_BitwiseOr';
  10863. }
  10864. }
  10865. <?php
  10866. declare (strict_types=1);
  10867. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10868. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10869. class BitwiseXor extends AssignOp
  10870. {
  10871. public function getType(): string
  10872. {
  10873. return 'Expr_AssignOp_BitwiseXor';
  10874. }
  10875. }
  10876. <?php
  10877. declare (strict_types=1);
  10878. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10879. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10880. class Coalesce extends AssignOp
  10881. {
  10882. public function getType(): string
  10883. {
  10884. return 'Expr_AssignOp_Coalesce';
  10885. }
  10886. }
  10887. <?php
  10888. declare (strict_types=1);
  10889. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10890. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10891. class Concat extends AssignOp
  10892. {
  10893. public function getType(): string
  10894. {
  10895. return 'Expr_AssignOp_Concat';
  10896. }
  10897. }
  10898. <?php
  10899. declare (strict_types=1);
  10900. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10901. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10902. class Div extends AssignOp
  10903. {
  10904. public function getType(): string
  10905. {
  10906. return 'Expr_AssignOp_Div';
  10907. }
  10908. }
  10909. <?php
  10910. declare (strict_types=1);
  10911. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10912. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10913. class Minus extends AssignOp
  10914. {
  10915. public function getType(): string
  10916. {
  10917. return 'Expr_AssignOp_Minus';
  10918. }
  10919. }
  10920. <?php
  10921. declare (strict_types=1);
  10922. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10923. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10924. class Mod extends AssignOp
  10925. {
  10926. public function getType(): string
  10927. {
  10928. return 'Expr_AssignOp_Mod';
  10929. }
  10930. }
  10931. <?php
  10932. declare (strict_types=1);
  10933. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10934. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10935. class Mul extends AssignOp
  10936. {
  10937. public function getType(): string
  10938. {
  10939. return 'Expr_AssignOp_Mul';
  10940. }
  10941. }
  10942. <?php
  10943. declare (strict_types=1);
  10944. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10945. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10946. class Plus extends AssignOp
  10947. {
  10948. public function getType(): string
  10949. {
  10950. return 'Expr_AssignOp_Plus';
  10951. }
  10952. }
  10953. <?php
  10954. declare (strict_types=1);
  10955. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10956. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10957. class Pow extends AssignOp
  10958. {
  10959. public function getType(): string
  10960. {
  10961. return 'Expr_AssignOp_Pow';
  10962. }
  10963. }
  10964. <?php
  10965. declare (strict_types=1);
  10966. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10967. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10968. class ShiftLeft extends AssignOp
  10969. {
  10970. public function getType(): string
  10971. {
  10972. return 'Expr_AssignOp_ShiftLeft';
  10973. }
  10974. }
  10975. <?php
  10976. declare (strict_types=1);
  10977. namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10978. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  10979. class ShiftRight extends AssignOp
  10980. {
  10981. public function getType(): string
  10982. {
  10983. return 'Expr_AssignOp_ShiftRight';
  10984. }
  10985. }
  10986. <?php
  10987. declare (strict_types=1);
  10988. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  10989. use PHPUnitPHAR\PhpParser\Node\Expr;
  10990. class AssignRef extends Expr
  10991. {
  10992. /** @var Expr Variable reference is assigned to */
  10993. public Expr $var;
  10994. /** @var Expr Variable which is referenced */
  10995. public Expr $expr;
  10996. /**
  10997. * Constructs an assignment node.
  10998. *
  10999. * @param Expr $var Variable
  11000. * @param Expr $expr Expression
  11001. * @param array<string, mixed> $attributes Additional attributes
  11002. */
  11003. public function __construct(Expr $var, Expr $expr, array $attributes = [])
  11004. {
  11005. $this->attributes = $attributes;
  11006. $this->var = $var;
  11007. $this->expr = $expr;
  11008. }
  11009. public function getSubNodeNames(): array
  11010. {
  11011. return ['var', 'expr'];
  11012. }
  11013. public function getType(): string
  11014. {
  11015. return 'Expr_AssignRef';
  11016. }
  11017. }
  11018. <?php
  11019. declare (strict_types=1);
  11020. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11021. use PHPUnitPHAR\PhpParser\Node\Expr;
  11022. abstract class BinaryOp extends Expr
  11023. {
  11024. /** @var Expr The left hand side expression */
  11025. public Expr $left;
  11026. /** @var Expr The right hand side expression */
  11027. public Expr $right;
  11028. /**
  11029. * Constructs a binary operator node.
  11030. *
  11031. * @param Expr $left The left hand side expression
  11032. * @param Expr $right The right hand side expression
  11033. * @param array<string, mixed> $attributes Additional attributes
  11034. */
  11035. public function __construct(Expr $left, Expr $right, array $attributes = [])
  11036. {
  11037. $this->attributes = $attributes;
  11038. $this->left = $left;
  11039. $this->right = $right;
  11040. }
  11041. public function getSubNodeNames(): array
  11042. {
  11043. return ['left', 'right'];
  11044. }
  11045. /**
  11046. * Get the operator sigil for this binary operation.
  11047. *
  11048. * In the case there are multiple possible sigils for an operator, this method does not
  11049. * necessarily return the one used in the parsed code.
  11050. */
  11051. abstract public function getOperatorSigil(): string;
  11052. }
  11053. <?php
  11054. declare (strict_types=1);
  11055. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11056. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11057. class BitwiseAnd extends BinaryOp
  11058. {
  11059. public function getOperatorSigil(): string
  11060. {
  11061. return '&';
  11062. }
  11063. public function getType(): string
  11064. {
  11065. return 'Expr_BinaryOp_BitwiseAnd';
  11066. }
  11067. }
  11068. <?php
  11069. declare (strict_types=1);
  11070. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11071. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11072. class BitwiseOr extends BinaryOp
  11073. {
  11074. public function getOperatorSigil(): string
  11075. {
  11076. return '|';
  11077. }
  11078. public function getType(): string
  11079. {
  11080. return 'Expr_BinaryOp_BitwiseOr';
  11081. }
  11082. }
  11083. <?php
  11084. declare (strict_types=1);
  11085. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11086. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11087. class BitwiseXor extends BinaryOp
  11088. {
  11089. public function getOperatorSigil(): string
  11090. {
  11091. return '^';
  11092. }
  11093. public function getType(): string
  11094. {
  11095. return 'Expr_BinaryOp_BitwiseXor';
  11096. }
  11097. }
  11098. <?php
  11099. declare (strict_types=1);
  11100. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11101. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11102. class BooleanAnd extends BinaryOp
  11103. {
  11104. public function getOperatorSigil(): string
  11105. {
  11106. return '&&';
  11107. }
  11108. public function getType(): string
  11109. {
  11110. return 'Expr_BinaryOp_BooleanAnd';
  11111. }
  11112. }
  11113. <?php
  11114. declare (strict_types=1);
  11115. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11116. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11117. class BooleanOr extends BinaryOp
  11118. {
  11119. public function getOperatorSigil(): string
  11120. {
  11121. return '||';
  11122. }
  11123. public function getType(): string
  11124. {
  11125. return 'Expr_BinaryOp_BooleanOr';
  11126. }
  11127. }
  11128. <?php
  11129. declare (strict_types=1);
  11130. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11131. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11132. class Coalesce extends BinaryOp
  11133. {
  11134. public function getOperatorSigil(): string
  11135. {
  11136. return '??';
  11137. }
  11138. public function getType(): string
  11139. {
  11140. return 'Expr_BinaryOp_Coalesce';
  11141. }
  11142. }
  11143. <?php
  11144. declare (strict_types=1);
  11145. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11146. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11147. class Concat extends BinaryOp
  11148. {
  11149. public function getOperatorSigil(): string
  11150. {
  11151. return '.';
  11152. }
  11153. public function getType(): string
  11154. {
  11155. return 'Expr_BinaryOp_Concat';
  11156. }
  11157. }
  11158. <?php
  11159. declare (strict_types=1);
  11160. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11161. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11162. class Div extends BinaryOp
  11163. {
  11164. public function getOperatorSigil(): string
  11165. {
  11166. return '/';
  11167. }
  11168. public function getType(): string
  11169. {
  11170. return 'Expr_BinaryOp_Div';
  11171. }
  11172. }
  11173. <?php
  11174. declare (strict_types=1);
  11175. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11176. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11177. class Equal extends BinaryOp
  11178. {
  11179. public function getOperatorSigil(): string
  11180. {
  11181. return '==';
  11182. }
  11183. public function getType(): string
  11184. {
  11185. return 'Expr_BinaryOp_Equal';
  11186. }
  11187. }
  11188. <?php
  11189. declare (strict_types=1);
  11190. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11191. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11192. class Greater extends BinaryOp
  11193. {
  11194. public function getOperatorSigil(): string
  11195. {
  11196. return '>';
  11197. }
  11198. public function getType(): string
  11199. {
  11200. return 'Expr_BinaryOp_Greater';
  11201. }
  11202. }
  11203. <?php
  11204. declare (strict_types=1);
  11205. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11206. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11207. class GreaterOrEqual extends BinaryOp
  11208. {
  11209. public function getOperatorSigil(): string
  11210. {
  11211. return '>=';
  11212. }
  11213. public function getType(): string
  11214. {
  11215. return 'Expr_BinaryOp_GreaterOrEqual';
  11216. }
  11217. }
  11218. <?php
  11219. declare (strict_types=1);
  11220. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11221. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11222. class Identical extends BinaryOp
  11223. {
  11224. public function getOperatorSigil(): string
  11225. {
  11226. return '===';
  11227. }
  11228. public function getType(): string
  11229. {
  11230. return 'Expr_BinaryOp_Identical';
  11231. }
  11232. }
  11233. <?php
  11234. declare (strict_types=1);
  11235. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11236. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11237. class LogicalAnd extends BinaryOp
  11238. {
  11239. public function getOperatorSigil(): string
  11240. {
  11241. return 'and';
  11242. }
  11243. public function getType(): string
  11244. {
  11245. return 'Expr_BinaryOp_LogicalAnd';
  11246. }
  11247. }
  11248. <?php
  11249. declare (strict_types=1);
  11250. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11251. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11252. class LogicalOr extends BinaryOp
  11253. {
  11254. public function getOperatorSigil(): string
  11255. {
  11256. return 'or';
  11257. }
  11258. public function getType(): string
  11259. {
  11260. return 'Expr_BinaryOp_LogicalOr';
  11261. }
  11262. }
  11263. <?php
  11264. declare (strict_types=1);
  11265. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11266. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11267. class LogicalXor extends BinaryOp
  11268. {
  11269. public function getOperatorSigil(): string
  11270. {
  11271. return 'xor';
  11272. }
  11273. public function getType(): string
  11274. {
  11275. return 'Expr_BinaryOp_LogicalXor';
  11276. }
  11277. }
  11278. <?php
  11279. declare (strict_types=1);
  11280. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11281. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11282. class Minus extends BinaryOp
  11283. {
  11284. public function getOperatorSigil(): string
  11285. {
  11286. return '-';
  11287. }
  11288. public function getType(): string
  11289. {
  11290. return 'Expr_BinaryOp_Minus';
  11291. }
  11292. }
  11293. <?php
  11294. declare (strict_types=1);
  11295. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11296. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11297. class Mod extends BinaryOp
  11298. {
  11299. public function getOperatorSigil(): string
  11300. {
  11301. return '%';
  11302. }
  11303. public function getType(): string
  11304. {
  11305. return 'Expr_BinaryOp_Mod';
  11306. }
  11307. }
  11308. <?php
  11309. declare (strict_types=1);
  11310. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11311. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11312. class Mul extends BinaryOp
  11313. {
  11314. public function getOperatorSigil(): string
  11315. {
  11316. return '*';
  11317. }
  11318. public function getType(): string
  11319. {
  11320. return 'Expr_BinaryOp_Mul';
  11321. }
  11322. }
  11323. <?php
  11324. declare (strict_types=1);
  11325. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11326. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11327. class NotEqual extends BinaryOp
  11328. {
  11329. public function getOperatorSigil(): string
  11330. {
  11331. return '!=';
  11332. }
  11333. public function getType(): string
  11334. {
  11335. return 'Expr_BinaryOp_NotEqual';
  11336. }
  11337. }
  11338. <?php
  11339. declare (strict_types=1);
  11340. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11341. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11342. class NotIdentical extends BinaryOp
  11343. {
  11344. public function getOperatorSigil(): string
  11345. {
  11346. return '!==';
  11347. }
  11348. public function getType(): string
  11349. {
  11350. return 'Expr_BinaryOp_NotIdentical';
  11351. }
  11352. }
  11353. <?php
  11354. declare (strict_types=1);
  11355. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11356. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11357. class Plus extends BinaryOp
  11358. {
  11359. public function getOperatorSigil(): string
  11360. {
  11361. return '+';
  11362. }
  11363. public function getType(): string
  11364. {
  11365. return 'Expr_BinaryOp_Plus';
  11366. }
  11367. }
  11368. <?php
  11369. declare (strict_types=1);
  11370. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11371. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11372. class Pow extends BinaryOp
  11373. {
  11374. public function getOperatorSigil(): string
  11375. {
  11376. return '**';
  11377. }
  11378. public function getType(): string
  11379. {
  11380. return 'Expr_BinaryOp_Pow';
  11381. }
  11382. }
  11383. <?php
  11384. declare (strict_types=1);
  11385. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11386. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11387. class ShiftLeft extends BinaryOp
  11388. {
  11389. public function getOperatorSigil(): string
  11390. {
  11391. return '<<';
  11392. }
  11393. public function getType(): string
  11394. {
  11395. return 'Expr_BinaryOp_ShiftLeft';
  11396. }
  11397. }
  11398. <?php
  11399. declare (strict_types=1);
  11400. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11401. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11402. class ShiftRight extends BinaryOp
  11403. {
  11404. public function getOperatorSigil(): string
  11405. {
  11406. return '>>';
  11407. }
  11408. public function getType(): string
  11409. {
  11410. return 'Expr_BinaryOp_ShiftRight';
  11411. }
  11412. }
  11413. <?php
  11414. declare (strict_types=1);
  11415. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11416. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11417. class Smaller extends BinaryOp
  11418. {
  11419. public function getOperatorSigil(): string
  11420. {
  11421. return '<';
  11422. }
  11423. public function getType(): string
  11424. {
  11425. return 'Expr_BinaryOp_Smaller';
  11426. }
  11427. }
  11428. <?php
  11429. declare (strict_types=1);
  11430. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11431. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11432. class SmallerOrEqual extends BinaryOp
  11433. {
  11434. public function getOperatorSigil(): string
  11435. {
  11436. return '<=';
  11437. }
  11438. public function getType(): string
  11439. {
  11440. return 'Expr_BinaryOp_SmallerOrEqual';
  11441. }
  11442. }
  11443. <?php
  11444. declare (strict_types=1);
  11445. namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11446. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  11447. class Spaceship extends BinaryOp
  11448. {
  11449. public function getOperatorSigil(): string
  11450. {
  11451. return '<=>';
  11452. }
  11453. public function getType(): string
  11454. {
  11455. return 'Expr_BinaryOp_Spaceship';
  11456. }
  11457. }
  11458. <?php
  11459. declare (strict_types=1);
  11460. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11461. use PHPUnitPHAR\PhpParser\Node\Expr;
  11462. class BitwiseNot extends Expr
  11463. {
  11464. /** @var Expr Expression */
  11465. public Expr $expr;
  11466. /**
  11467. * Constructs a bitwise not node.
  11468. *
  11469. * @param Expr $expr Expression
  11470. * @param array<string, mixed> $attributes Additional attributes
  11471. */
  11472. public function __construct(Expr $expr, array $attributes = [])
  11473. {
  11474. $this->attributes = $attributes;
  11475. $this->expr = $expr;
  11476. }
  11477. public function getSubNodeNames(): array
  11478. {
  11479. return ['expr'];
  11480. }
  11481. public function getType(): string
  11482. {
  11483. return 'Expr_BitwiseNot';
  11484. }
  11485. }
  11486. <?php
  11487. declare (strict_types=1);
  11488. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11489. use PHPUnitPHAR\PhpParser\Node\Expr;
  11490. class BooleanNot extends Expr
  11491. {
  11492. /** @var Expr Expression */
  11493. public Expr $expr;
  11494. /**
  11495. * Constructs a boolean not node.
  11496. *
  11497. * @param Expr $expr Expression
  11498. * @param array<string, mixed> $attributes Additional attributes
  11499. */
  11500. public function __construct(Expr $expr, array $attributes = [])
  11501. {
  11502. $this->attributes = $attributes;
  11503. $this->expr = $expr;
  11504. }
  11505. public function getSubNodeNames(): array
  11506. {
  11507. return ['expr'];
  11508. }
  11509. public function getType(): string
  11510. {
  11511. return 'Expr_BooleanNot';
  11512. }
  11513. }
  11514. <?php
  11515. declare (strict_types=1);
  11516. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11517. use PHPUnitPHAR\PhpParser\Node\Arg;
  11518. use PHPUnitPHAR\PhpParser\Node\Expr;
  11519. use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
  11520. abstract class CallLike extends Expr
  11521. {
  11522. /**
  11523. * Return raw arguments, which may be actual Args, or VariadicPlaceholders for first-class
  11524. * callables.
  11525. *
  11526. * @return array<Arg|VariadicPlaceholder>
  11527. */
  11528. abstract public function getRawArgs(): array;
  11529. /**
  11530. * Returns whether this call expression is actually a first class callable.
  11531. */
  11532. public function isFirstClassCallable(): bool
  11533. {
  11534. $rawArgs = $this->getRawArgs();
  11535. return count($rawArgs) === 1 && current($rawArgs) instanceof VariadicPlaceholder;
  11536. }
  11537. /**
  11538. * Assert that this is not a first-class callable and return only ordinary Args.
  11539. *
  11540. * @return Arg[]
  11541. */
  11542. public function getArgs(): array
  11543. {
  11544. assert(!$this->isFirstClassCallable());
  11545. return $this->getRawArgs();
  11546. }
  11547. }
  11548. <?php
  11549. declare (strict_types=1);
  11550. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11551. use PHPUnitPHAR\PhpParser\Node\Expr;
  11552. abstract class Cast extends Expr
  11553. {
  11554. /** @var Expr Expression */
  11555. public Expr $expr;
  11556. /**
  11557. * Constructs a cast node.
  11558. *
  11559. * @param Expr $expr Expression
  11560. * @param array<string, mixed> $attributes Additional attributes
  11561. */
  11562. public function __construct(Expr $expr, array $attributes = [])
  11563. {
  11564. $this->attributes = $attributes;
  11565. $this->expr = $expr;
  11566. }
  11567. public function getSubNodeNames(): array
  11568. {
  11569. return ['expr'];
  11570. }
  11571. }
  11572. <?php
  11573. declare (strict_types=1);
  11574. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11575. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11576. class Array_ extends Cast
  11577. {
  11578. public function getType(): string
  11579. {
  11580. return 'Expr_Cast_Array';
  11581. }
  11582. }
  11583. <?php
  11584. declare (strict_types=1);
  11585. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11586. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11587. class Bool_ extends Cast
  11588. {
  11589. public function getType(): string
  11590. {
  11591. return 'Expr_Cast_Bool';
  11592. }
  11593. }
  11594. <?php
  11595. declare (strict_types=1);
  11596. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11597. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11598. class Double extends Cast
  11599. {
  11600. // For use in "kind" attribute
  11601. public const KIND_DOUBLE = 1;
  11602. // "double" syntax
  11603. public const KIND_FLOAT = 2;
  11604. // "float" syntax
  11605. public const KIND_REAL = 3;
  11606. // "real" syntax
  11607. public function getType(): string
  11608. {
  11609. return 'Expr_Cast_Double';
  11610. }
  11611. }
  11612. <?php
  11613. declare (strict_types=1);
  11614. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11615. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11616. class Int_ extends Cast
  11617. {
  11618. public function getType(): string
  11619. {
  11620. return 'Expr_Cast_Int';
  11621. }
  11622. }
  11623. <?php
  11624. declare (strict_types=1);
  11625. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11626. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11627. class Object_ extends Cast
  11628. {
  11629. public function getType(): string
  11630. {
  11631. return 'Expr_Cast_Object';
  11632. }
  11633. }
  11634. <?php
  11635. declare (strict_types=1);
  11636. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11637. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11638. class String_ extends Cast
  11639. {
  11640. public function getType(): string
  11641. {
  11642. return 'Expr_Cast_String';
  11643. }
  11644. }
  11645. <?php
  11646. declare (strict_types=1);
  11647. namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11648. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  11649. class Unset_ extends Cast
  11650. {
  11651. public function getType(): string
  11652. {
  11653. return 'Expr_Cast_Unset';
  11654. }
  11655. }
  11656. <?php
  11657. declare (strict_types=1);
  11658. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11659. use PHPUnitPHAR\PhpParser\Node;
  11660. use PHPUnitPHAR\PhpParser\Node\Expr;
  11661. use PHPUnitPHAR\PhpParser\Node\Identifier;
  11662. use PHPUnitPHAR\PhpParser\Node\Name;
  11663. class ClassConstFetch extends Expr
  11664. {
  11665. /** @var Name|Expr Class name */
  11666. public Node $class;
  11667. /** @var Identifier|Expr|Error Constant name */
  11668. public Node $name;
  11669. /**
  11670. * Constructs a class const fetch node.
  11671. *
  11672. * @param Name|Expr $class Class name
  11673. * @param string|Identifier|Expr|Error $name Constant name
  11674. * @param array<string, mixed> $attributes Additional attributes
  11675. */
  11676. public function __construct(Node $class, $name, array $attributes = [])
  11677. {
  11678. $this->attributes = $attributes;
  11679. $this->class = $class;
  11680. $this->name = \is_string($name) ? new Identifier($name) : $name;
  11681. }
  11682. public function getSubNodeNames(): array
  11683. {
  11684. return ['class', 'name'];
  11685. }
  11686. public function getType(): string
  11687. {
  11688. return 'Expr_ClassConstFetch';
  11689. }
  11690. }
  11691. <?php
  11692. declare (strict_types=1);
  11693. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11694. use PHPUnitPHAR\PhpParser\Node\Expr;
  11695. class Clone_ extends Expr
  11696. {
  11697. /** @var Expr Expression */
  11698. public Expr $expr;
  11699. /**
  11700. * Constructs a clone node.
  11701. *
  11702. * @param Expr $expr Expression
  11703. * @param array<string, mixed> $attributes Additional attributes
  11704. */
  11705. public function __construct(Expr $expr, array $attributes = [])
  11706. {
  11707. $this->attributes = $attributes;
  11708. $this->expr = $expr;
  11709. }
  11710. public function getSubNodeNames(): array
  11711. {
  11712. return ['expr'];
  11713. }
  11714. public function getType(): string
  11715. {
  11716. return 'Expr_Clone';
  11717. }
  11718. }
  11719. <?php
  11720. declare (strict_types=1);
  11721. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11722. use PHPUnitPHAR\PhpParser\Node;
  11723. use PHPUnitPHAR\PhpParser\Node\ClosureUse;
  11724. use PHPUnitPHAR\PhpParser\Node\Expr;
  11725. use PHPUnitPHAR\PhpParser\Node\FunctionLike;
  11726. class Closure extends Expr implements FunctionLike
  11727. {
  11728. /** @var bool Whether the closure is static */
  11729. public bool $static;
  11730. /** @var bool Whether to return by reference */
  11731. public bool $byRef;
  11732. /** @var Node\Param[] Parameters */
  11733. public array $params;
  11734. /** @var ClosureUse[] use()s */
  11735. public array $uses;
  11736. /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
  11737. public ?Node $returnType;
  11738. /** @var Node\Stmt[] Statements */
  11739. public array $stmts;
  11740. /** @var Node\AttributeGroup[] PHP attribute groups */
  11741. public array $attrGroups;
  11742. /**
  11743. * Constructs a lambda function node.
  11744. *
  11745. * @param array{
  11746. * static?: bool,
  11747. * byRef?: bool,
  11748. * params?: Node\Param[],
  11749. * uses?: ClosureUse[],
  11750. * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
  11751. * stmts?: Node\Stmt[],
  11752. * attrGroups?: Node\AttributeGroup[],
  11753. * } $subNodes Array of the following optional subnodes:
  11754. * 'static' => false : Whether the closure is static
  11755. * 'byRef' => false : Whether to return by reference
  11756. * 'params' => array(): Parameters
  11757. * 'uses' => array(): use()s
  11758. * 'returnType' => null : Return type
  11759. * 'stmts' => array(): Statements
  11760. * 'attrGroups' => array(): PHP attributes groups
  11761. * @param array<string, mixed> $attributes Additional attributes
  11762. */
  11763. public function __construct(array $subNodes = [], array $attributes = [])
  11764. {
  11765. $this->attributes = $attributes;
  11766. $this->static = $subNodes['static'] ?? \false;
  11767. $this->byRef = $subNodes['byRef'] ?? \false;
  11768. $this->params = $subNodes['params'] ?? [];
  11769. $this->uses = $subNodes['uses'] ?? [];
  11770. $this->returnType = $subNodes['returnType'] ?? null;
  11771. $this->stmts = $subNodes['stmts'] ?? [];
  11772. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  11773. }
  11774. public function getSubNodeNames(): array
  11775. {
  11776. return ['attrGroups', 'static', 'byRef', 'params', 'uses', 'returnType', 'stmts'];
  11777. }
  11778. public function returnsByRef(): bool
  11779. {
  11780. return $this->byRef;
  11781. }
  11782. public function getParams(): array
  11783. {
  11784. return $this->params;
  11785. }
  11786. public function getReturnType()
  11787. {
  11788. return $this->returnType;
  11789. }
  11790. /** @return Node\Stmt[] */
  11791. public function getStmts(): array
  11792. {
  11793. return $this->stmts;
  11794. }
  11795. public function getAttrGroups(): array
  11796. {
  11797. return $this->attrGroups;
  11798. }
  11799. public function getType(): string
  11800. {
  11801. return 'Expr_Closure';
  11802. }
  11803. }
  11804. <?php
  11805. declare (strict_types=1);
  11806. namespace PHPUnitPHAR;
  11807. require __DIR__ . '/../ClosureUse.php';
  11808. <?php
  11809. declare (strict_types=1);
  11810. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11811. use PHPUnitPHAR\PhpParser\Node\Expr;
  11812. use PHPUnitPHAR\PhpParser\Node\Name;
  11813. class ConstFetch extends Expr
  11814. {
  11815. /** @var Name Constant name */
  11816. public Name $name;
  11817. /**
  11818. * Constructs a const fetch node.
  11819. *
  11820. * @param Name $name Constant name
  11821. * @param array<string, mixed> $attributes Additional attributes
  11822. */
  11823. public function __construct(Name $name, array $attributes = [])
  11824. {
  11825. $this->attributes = $attributes;
  11826. $this->name = $name;
  11827. }
  11828. public function getSubNodeNames(): array
  11829. {
  11830. return ['name'];
  11831. }
  11832. public function getType(): string
  11833. {
  11834. return 'Expr_ConstFetch';
  11835. }
  11836. }
  11837. <?php
  11838. declare (strict_types=1);
  11839. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11840. use PHPUnitPHAR\PhpParser\Node\Expr;
  11841. class Empty_ extends Expr
  11842. {
  11843. /** @var Expr Expression */
  11844. public Expr $expr;
  11845. /**
  11846. * Constructs an empty() node.
  11847. *
  11848. * @param Expr $expr Expression
  11849. * @param array<string, mixed> $attributes Additional attributes
  11850. */
  11851. public function __construct(Expr $expr, array $attributes = [])
  11852. {
  11853. $this->attributes = $attributes;
  11854. $this->expr = $expr;
  11855. }
  11856. public function getSubNodeNames(): array
  11857. {
  11858. return ['expr'];
  11859. }
  11860. public function getType(): string
  11861. {
  11862. return 'Expr_Empty';
  11863. }
  11864. }
  11865. <?php
  11866. declare (strict_types=1);
  11867. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11868. use PHPUnitPHAR\PhpParser\Node\Expr;
  11869. /**
  11870. * Error node used during parsing with error recovery.
  11871. *
  11872. * An error node may be placed at a position where an expression is required, but an error occurred.
  11873. * Error nodes will not be present if the parser is run in throwOnError mode (the default).
  11874. */
  11875. class Error extends Expr
  11876. {
  11877. /**
  11878. * Constructs an error node.
  11879. *
  11880. * @param array<string, mixed> $attributes Additional attributes
  11881. */
  11882. public function __construct(array $attributes = [])
  11883. {
  11884. $this->attributes = $attributes;
  11885. }
  11886. public function getSubNodeNames(): array
  11887. {
  11888. return [];
  11889. }
  11890. public function getType(): string
  11891. {
  11892. return 'Expr_Error';
  11893. }
  11894. }
  11895. <?php
  11896. declare (strict_types=1);
  11897. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11898. use PHPUnitPHAR\PhpParser\Node\Expr;
  11899. class ErrorSuppress extends Expr
  11900. {
  11901. /** @var Expr Expression */
  11902. public Expr $expr;
  11903. /**
  11904. * Constructs an error suppress node.
  11905. *
  11906. * @param Expr $expr Expression
  11907. * @param array<string, mixed> $attributes Additional attributes
  11908. */
  11909. public function __construct(Expr $expr, array $attributes = [])
  11910. {
  11911. $this->attributes = $attributes;
  11912. $this->expr = $expr;
  11913. }
  11914. public function getSubNodeNames(): array
  11915. {
  11916. return ['expr'];
  11917. }
  11918. public function getType(): string
  11919. {
  11920. return 'Expr_ErrorSuppress';
  11921. }
  11922. }
  11923. <?php
  11924. declare (strict_types=1);
  11925. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11926. use PHPUnitPHAR\PhpParser\Node\Expr;
  11927. class Eval_ extends Expr
  11928. {
  11929. /** @var Expr Expression */
  11930. public Expr $expr;
  11931. /**
  11932. * Constructs an eval() node.
  11933. *
  11934. * @param Expr $expr Expression
  11935. * @param array<string, mixed> $attributes Additional attributes
  11936. */
  11937. public function __construct(Expr $expr, array $attributes = [])
  11938. {
  11939. $this->attributes = $attributes;
  11940. $this->expr = $expr;
  11941. }
  11942. public function getSubNodeNames(): array
  11943. {
  11944. return ['expr'];
  11945. }
  11946. public function getType(): string
  11947. {
  11948. return 'Expr_Eval';
  11949. }
  11950. }
  11951. <?php
  11952. declare (strict_types=1);
  11953. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11954. use PHPUnitPHAR\PhpParser\Node\Expr;
  11955. class Exit_ extends Expr
  11956. {
  11957. /* For use in "kind" attribute */
  11958. public const KIND_EXIT = 1;
  11959. public const KIND_DIE = 2;
  11960. /** @var null|Expr Expression */
  11961. public ?Expr $expr;
  11962. /**
  11963. * Constructs an exit() node.
  11964. *
  11965. * @param null|Expr $expr Expression
  11966. * @param array<string, mixed> $attributes Additional attributes
  11967. */
  11968. public function __construct(?Expr $expr = null, array $attributes = [])
  11969. {
  11970. $this->attributes = $attributes;
  11971. $this->expr = $expr;
  11972. }
  11973. public function getSubNodeNames(): array
  11974. {
  11975. return ['expr'];
  11976. }
  11977. public function getType(): string
  11978. {
  11979. return 'Expr_Exit';
  11980. }
  11981. }
  11982. <?php
  11983. declare (strict_types=1);
  11984. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  11985. use PHPUnitPHAR\PhpParser\Node;
  11986. use PHPUnitPHAR\PhpParser\Node\Expr;
  11987. class FuncCall extends CallLike
  11988. {
  11989. /** @var Node\Name|Expr Function name */
  11990. public Node $name;
  11991. /** @var array<Node\Arg|Node\VariadicPlaceholder> Arguments */
  11992. public array $args;
  11993. /**
  11994. * Constructs a function call node.
  11995. *
  11996. * @param Node\Name|Expr $name Function name
  11997. * @param array<Node\Arg|Node\VariadicPlaceholder> $args Arguments
  11998. * @param array<string, mixed> $attributes Additional attributes
  11999. */
  12000. public function __construct(Node $name, array $args = [], array $attributes = [])
  12001. {
  12002. $this->attributes = $attributes;
  12003. $this->name = $name;
  12004. $this->args = $args;
  12005. }
  12006. public function getSubNodeNames(): array
  12007. {
  12008. return ['name', 'args'];
  12009. }
  12010. public function getType(): string
  12011. {
  12012. return 'Expr_FuncCall';
  12013. }
  12014. public function getRawArgs(): array
  12015. {
  12016. return $this->args;
  12017. }
  12018. }
  12019. <?php
  12020. declare (strict_types=1);
  12021. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12022. use PHPUnitPHAR\PhpParser\Node\Expr;
  12023. class Include_ extends Expr
  12024. {
  12025. public const TYPE_INCLUDE = 1;
  12026. public const TYPE_INCLUDE_ONCE = 2;
  12027. public const TYPE_REQUIRE = 3;
  12028. public const TYPE_REQUIRE_ONCE = 4;
  12029. /** @var Expr Expression */
  12030. public Expr $expr;
  12031. /** @var int Type of include */
  12032. public int $type;
  12033. /**
  12034. * Constructs an include node.
  12035. *
  12036. * @param Expr $expr Expression
  12037. * @param int $type Type of include
  12038. * @param array<string, mixed> $attributes Additional attributes
  12039. */
  12040. public function __construct(Expr $expr, int $type, array $attributes = [])
  12041. {
  12042. $this->attributes = $attributes;
  12043. $this->expr = $expr;
  12044. $this->type = $type;
  12045. }
  12046. public function getSubNodeNames(): array
  12047. {
  12048. return ['expr', 'type'];
  12049. }
  12050. public function getType(): string
  12051. {
  12052. return 'Expr_Include';
  12053. }
  12054. }
  12055. <?php
  12056. declare (strict_types=1);
  12057. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12058. use PHPUnitPHAR\PhpParser\Node;
  12059. use PHPUnitPHAR\PhpParser\Node\Expr;
  12060. use PHPUnitPHAR\PhpParser\Node\Name;
  12061. class Instanceof_ extends Expr
  12062. {
  12063. /** @var Expr Expression */
  12064. public Expr $expr;
  12065. /** @var Name|Expr Class name */
  12066. public Node $class;
  12067. /**
  12068. * Constructs an instanceof check node.
  12069. *
  12070. * @param Expr $expr Expression
  12071. * @param Name|Expr $class Class name
  12072. * @param array<string, mixed> $attributes Additional attributes
  12073. */
  12074. public function __construct(Expr $expr, Node $class, array $attributes = [])
  12075. {
  12076. $this->attributes = $attributes;
  12077. $this->expr = $expr;
  12078. $this->class = $class;
  12079. }
  12080. public function getSubNodeNames(): array
  12081. {
  12082. return ['expr', 'class'];
  12083. }
  12084. public function getType(): string
  12085. {
  12086. return 'Expr_Instanceof';
  12087. }
  12088. }
  12089. <?php
  12090. declare (strict_types=1);
  12091. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12092. use PHPUnitPHAR\PhpParser\Node\Expr;
  12093. class Isset_ extends Expr
  12094. {
  12095. /** @var Expr[] Variables */
  12096. public array $vars;
  12097. /**
  12098. * Constructs an array node.
  12099. *
  12100. * @param Expr[] $vars Variables
  12101. * @param array<string, mixed> $attributes Additional attributes
  12102. */
  12103. public function __construct(array $vars, array $attributes = [])
  12104. {
  12105. $this->attributes = $attributes;
  12106. $this->vars = $vars;
  12107. }
  12108. public function getSubNodeNames(): array
  12109. {
  12110. return ['vars'];
  12111. }
  12112. public function getType(): string
  12113. {
  12114. return 'Expr_Isset';
  12115. }
  12116. }
  12117. <?php
  12118. declare (strict_types=1);
  12119. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12120. use PHPUnitPHAR\PhpParser\Node\ArrayItem;
  12121. use PHPUnitPHAR\PhpParser\Node\Expr;
  12122. class List_ extends Expr
  12123. {
  12124. // For use in "kind" attribute
  12125. public const KIND_LIST = 1;
  12126. // list() syntax
  12127. public const KIND_ARRAY = 2;
  12128. // [] syntax
  12129. /** @var (ArrayItem|null)[] List of items to assign to */
  12130. public array $items;
  12131. /**
  12132. * Constructs a list() destructuring node.
  12133. *
  12134. * @param (ArrayItem|null)[] $items List of items to assign to
  12135. * @param array<string, mixed> $attributes Additional attributes
  12136. */
  12137. public function __construct(array $items, array $attributes = [])
  12138. {
  12139. $this->attributes = $attributes;
  12140. $this->items = $items;
  12141. }
  12142. public function getSubNodeNames(): array
  12143. {
  12144. return ['items'];
  12145. }
  12146. public function getType(): string
  12147. {
  12148. return 'Expr_List';
  12149. }
  12150. }
  12151. <?php
  12152. declare (strict_types=1);
  12153. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12154. use PHPUnitPHAR\PhpParser\Node;
  12155. use PHPUnitPHAR\PhpParser\Node\MatchArm;
  12156. class Match_ extends Node\Expr
  12157. {
  12158. /** @var Node\Expr Condition */
  12159. public Node\Expr $cond;
  12160. /** @var MatchArm[] */
  12161. public array $arms;
  12162. /**
  12163. * @param Node\Expr $cond Condition
  12164. * @param MatchArm[] $arms
  12165. * @param array<string, mixed> $attributes Additional attributes
  12166. */
  12167. public function __construct(Node\Expr $cond, array $arms = [], array $attributes = [])
  12168. {
  12169. $this->attributes = $attributes;
  12170. $this->cond = $cond;
  12171. $this->arms = $arms;
  12172. }
  12173. public function getSubNodeNames(): array
  12174. {
  12175. return ['cond', 'arms'];
  12176. }
  12177. public function getType(): string
  12178. {
  12179. return 'Expr_Match';
  12180. }
  12181. }
  12182. <?php
  12183. declare (strict_types=1);
  12184. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12185. use PHPUnitPHAR\PhpParser\Node;
  12186. use PHPUnitPHAR\PhpParser\Node\Arg;
  12187. use PHPUnitPHAR\PhpParser\Node\Expr;
  12188. use PHPUnitPHAR\PhpParser\Node\Identifier;
  12189. use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
  12190. class MethodCall extends CallLike
  12191. {
  12192. /** @var Expr Variable holding object */
  12193. public Expr $var;
  12194. /** @var Identifier|Expr Method name */
  12195. public Node $name;
  12196. /** @var array<Arg|VariadicPlaceholder> Arguments */
  12197. public array $args;
  12198. /**
  12199. * Constructs a function call node.
  12200. *
  12201. * @param Expr $var Variable holding object
  12202. * @param string|Identifier|Expr $name Method name
  12203. * @param array<Arg|VariadicPlaceholder> $args Arguments
  12204. * @param array<string, mixed> $attributes Additional attributes
  12205. */
  12206. public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
  12207. {
  12208. $this->attributes = $attributes;
  12209. $this->var = $var;
  12210. $this->name = \is_string($name) ? new Identifier($name) : $name;
  12211. $this->args = $args;
  12212. }
  12213. public function getSubNodeNames(): array
  12214. {
  12215. return ['var', 'name', 'args'];
  12216. }
  12217. public function getType(): string
  12218. {
  12219. return 'Expr_MethodCall';
  12220. }
  12221. public function getRawArgs(): array
  12222. {
  12223. return $this->args;
  12224. }
  12225. }
  12226. <?php
  12227. declare (strict_types=1);
  12228. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12229. use PHPUnitPHAR\PhpParser\Node;
  12230. use PHPUnitPHAR\PhpParser\Node\Arg;
  12231. use PHPUnitPHAR\PhpParser\Node\Expr;
  12232. use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
  12233. class New_ extends CallLike
  12234. {
  12235. /** @var Node\Name|Expr|Node\Stmt\Class_ Class name */
  12236. public Node $class;
  12237. /** @var array<Arg|VariadicPlaceholder> Arguments */
  12238. public array $args;
  12239. /**
  12240. * Constructs a function call node.
  12241. *
  12242. * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes)
  12243. * @param array<Arg|VariadicPlaceholder> $args Arguments
  12244. * @param array<string, mixed> $attributes Additional attributes
  12245. */
  12246. public function __construct(Node $class, array $args = [], array $attributes = [])
  12247. {
  12248. $this->attributes = $attributes;
  12249. $this->class = $class;
  12250. $this->args = $args;
  12251. }
  12252. public function getSubNodeNames(): array
  12253. {
  12254. return ['class', 'args'];
  12255. }
  12256. public function getType(): string
  12257. {
  12258. return 'Expr_New';
  12259. }
  12260. public function getRawArgs(): array
  12261. {
  12262. return $this->args;
  12263. }
  12264. }
  12265. <?php
  12266. declare (strict_types=1);
  12267. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12268. use PHPUnitPHAR\PhpParser\Node;
  12269. use PHPUnitPHAR\PhpParser\Node\Arg;
  12270. use PHPUnitPHAR\PhpParser\Node\Expr;
  12271. use PHPUnitPHAR\PhpParser\Node\Identifier;
  12272. use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
  12273. class NullsafeMethodCall extends CallLike
  12274. {
  12275. /** @var Expr Variable holding object */
  12276. public Expr $var;
  12277. /** @var Identifier|Expr Method name */
  12278. public Node $name;
  12279. /** @var array<Arg|VariadicPlaceholder> Arguments */
  12280. public array $args;
  12281. /**
  12282. * Constructs a nullsafe method call node.
  12283. *
  12284. * @param Expr $var Variable holding object
  12285. * @param string|Identifier|Expr $name Method name
  12286. * @param array<Arg|VariadicPlaceholder> $args Arguments
  12287. * @param array<string, mixed> $attributes Additional attributes
  12288. */
  12289. public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
  12290. {
  12291. $this->attributes = $attributes;
  12292. $this->var = $var;
  12293. $this->name = \is_string($name) ? new Identifier($name) : $name;
  12294. $this->args = $args;
  12295. }
  12296. public function getSubNodeNames(): array
  12297. {
  12298. return ['var', 'name', 'args'];
  12299. }
  12300. public function getType(): string
  12301. {
  12302. return 'Expr_NullsafeMethodCall';
  12303. }
  12304. public function getRawArgs(): array
  12305. {
  12306. return $this->args;
  12307. }
  12308. }
  12309. <?php
  12310. declare (strict_types=1);
  12311. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12312. use PHPUnitPHAR\PhpParser\Node;
  12313. use PHPUnitPHAR\PhpParser\Node\Expr;
  12314. use PHPUnitPHAR\PhpParser\Node\Identifier;
  12315. class NullsafePropertyFetch extends Expr
  12316. {
  12317. /** @var Expr Variable holding object */
  12318. public Expr $var;
  12319. /** @var Identifier|Expr Property name */
  12320. public Node $name;
  12321. /**
  12322. * Constructs a nullsafe property fetch node.
  12323. *
  12324. * @param Expr $var Variable holding object
  12325. * @param string|Identifier|Expr $name Property name
  12326. * @param array<string, mixed> $attributes Additional attributes
  12327. */
  12328. public function __construct(Expr $var, $name, array $attributes = [])
  12329. {
  12330. $this->attributes = $attributes;
  12331. $this->var = $var;
  12332. $this->name = \is_string($name) ? new Identifier($name) : $name;
  12333. }
  12334. public function getSubNodeNames(): array
  12335. {
  12336. return ['var', 'name'];
  12337. }
  12338. public function getType(): string
  12339. {
  12340. return 'Expr_NullsafePropertyFetch';
  12341. }
  12342. }
  12343. <?php
  12344. declare (strict_types=1);
  12345. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12346. use PHPUnitPHAR\PhpParser\Node\Expr;
  12347. class PostDec extends Expr
  12348. {
  12349. /** @var Expr Variable */
  12350. public Expr $var;
  12351. /**
  12352. * Constructs a post decrement node.
  12353. *
  12354. * @param Expr $var Variable
  12355. * @param array<string, mixed> $attributes Additional attributes
  12356. */
  12357. public function __construct(Expr $var, array $attributes = [])
  12358. {
  12359. $this->attributes = $attributes;
  12360. $this->var = $var;
  12361. }
  12362. public function getSubNodeNames(): array
  12363. {
  12364. return ['var'];
  12365. }
  12366. public function getType(): string
  12367. {
  12368. return 'Expr_PostDec';
  12369. }
  12370. }
  12371. <?php
  12372. declare (strict_types=1);
  12373. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12374. use PHPUnitPHAR\PhpParser\Node\Expr;
  12375. class PostInc extends Expr
  12376. {
  12377. /** @var Expr Variable */
  12378. public Expr $var;
  12379. /**
  12380. * Constructs a post increment node.
  12381. *
  12382. * @param Expr $var Variable
  12383. * @param array<string, mixed> $attributes Additional attributes
  12384. */
  12385. public function __construct(Expr $var, array $attributes = [])
  12386. {
  12387. $this->attributes = $attributes;
  12388. $this->var = $var;
  12389. }
  12390. public function getSubNodeNames(): array
  12391. {
  12392. return ['var'];
  12393. }
  12394. public function getType(): string
  12395. {
  12396. return 'Expr_PostInc';
  12397. }
  12398. }
  12399. <?php
  12400. declare (strict_types=1);
  12401. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12402. use PHPUnitPHAR\PhpParser\Node\Expr;
  12403. class PreDec extends Expr
  12404. {
  12405. /** @var Expr Variable */
  12406. public Expr $var;
  12407. /**
  12408. * Constructs a pre decrement node.
  12409. *
  12410. * @param Expr $var Variable
  12411. * @param array<string, mixed> $attributes Additional attributes
  12412. */
  12413. public function __construct(Expr $var, array $attributes = [])
  12414. {
  12415. $this->attributes = $attributes;
  12416. $this->var = $var;
  12417. }
  12418. public function getSubNodeNames(): array
  12419. {
  12420. return ['var'];
  12421. }
  12422. public function getType(): string
  12423. {
  12424. return 'Expr_PreDec';
  12425. }
  12426. }
  12427. <?php
  12428. declare (strict_types=1);
  12429. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12430. use PHPUnitPHAR\PhpParser\Node\Expr;
  12431. class PreInc extends Expr
  12432. {
  12433. /** @var Expr Variable */
  12434. public Expr $var;
  12435. /**
  12436. * Constructs a pre increment node.
  12437. *
  12438. * @param Expr $var Variable
  12439. * @param array<string, mixed> $attributes Additional attributes
  12440. */
  12441. public function __construct(Expr $var, array $attributes = [])
  12442. {
  12443. $this->attributes = $attributes;
  12444. $this->var = $var;
  12445. }
  12446. public function getSubNodeNames(): array
  12447. {
  12448. return ['var'];
  12449. }
  12450. public function getType(): string
  12451. {
  12452. return 'Expr_PreInc';
  12453. }
  12454. }
  12455. <?php
  12456. declare (strict_types=1);
  12457. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12458. use PHPUnitPHAR\PhpParser\Node\Expr;
  12459. class Print_ extends Expr
  12460. {
  12461. /** @var Expr Expression */
  12462. public Expr $expr;
  12463. /**
  12464. * Constructs an print() node.
  12465. *
  12466. * @param Expr $expr Expression
  12467. * @param array<string, mixed> $attributes Additional attributes
  12468. */
  12469. public function __construct(Expr $expr, array $attributes = [])
  12470. {
  12471. $this->attributes = $attributes;
  12472. $this->expr = $expr;
  12473. }
  12474. public function getSubNodeNames(): array
  12475. {
  12476. return ['expr'];
  12477. }
  12478. public function getType(): string
  12479. {
  12480. return 'Expr_Print';
  12481. }
  12482. }
  12483. <?php
  12484. declare (strict_types=1);
  12485. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12486. use PHPUnitPHAR\PhpParser\Node;
  12487. use PHPUnitPHAR\PhpParser\Node\Expr;
  12488. use PHPUnitPHAR\PhpParser\Node\Identifier;
  12489. class PropertyFetch extends Expr
  12490. {
  12491. /** @var Expr Variable holding object */
  12492. public Expr $var;
  12493. /** @var Identifier|Expr Property name */
  12494. public Node $name;
  12495. /**
  12496. * Constructs a function call node.
  12497. *
  12498. * @param Expr $var Variable holding object
  12499. * @param string|Identifier|Expr $name Property name
  12500. * @param array<string, mixed> $attributes Additional attributes
  12501. */
  12502. public function __construct(Expr $var, $name, array $attributes = [])
  12503. {
  12504. $this->attributes = $attributes;
  12505. $this->var = $var;
  12506. $this->name = \is_string($name) ? new Identifier($name) : $name;
  12507. }
  12508. public function getSubNodeNames(): array
  12509. {
  12510. return ['var', 'name'];
  12511. }
  12512. public function getType(): string
  12513. {
  12514. return 'Expr_PropertyFetch';
  12515. }
  12516. }
  12517. <?php
  12518. declare (strict_types=1);
  12519. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12520. use PHPUnitPHAR\PhpParser\Node\Expr;
  12521. use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
  12522. class ShellExec extends Expr
  12523. {
  12524. /** @var (Expr|InterpolatedStringPart)[] Interpolated string array */
  12525. public array $parts;
  12526. /**
  12527. * Constructs a shell exec (backtick) node.
  12528. *
  12529. * @param (Expr|InterpolatedStringPart)[] $parts Interpolated string array
  12530. * @param array<string, mixed> $attributes Additional attributes
  12531. */
  12532. public function __construct(array $parts, array $attributes = [])
  12533. {
  12534. $this->attributes = $attributes;
  12535. $this->parts = $parts;
  12536. }
  12537. public function getSubNodeNames(): array
  12538. {
  12539. return ['parts'];
  12540. }
  12541. public function getType(): string
  12542. {
  12543. return 'Expr_ShellExec';
  12544. }
  12545. }
  12546. <?php
  12547. declare (strict_types=1);
  12548. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12549. use PHPUnitPHAR\PhpParser\Node;
  12550. use PHPUnitPHAR\PhpParser\Node\Arg;
  12551. use PHPUnitPHAR\PhpParser\Node\Expr;
  12552. use PHPUnitPHAR\PhpParser\Node\Identifier;
  12553. use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
  12554. class StaticCall extends CallLike
  12555. {
  12556. /** @var Node\Name|Expr Class name */
  12557. public Node $class;
  12558. /** @var Identifier|Expr Method name */
  12559. public Node $name;
  12560. /** @var array<Arg|VariadicPlaceholder> Arguments */
  12561. public array $args;
  12562. /**
  12563. * Constructs a static method call node.
  12564. *
  12565. * @param Node\Name|Expr $class Class name
  12566. * @param string|Identifier|Expr $name Method name
  12567. * @param array<Arg|VariadicPlaceholder> $args Arguments
  12568. * @param array<string, mixed> $attributes Additional attributes
  12569. */
  12570. public function __construct(Node $class, $name, array $args = [], array $attributes = [])
  12571. {
  12572. $this->attributes = $attributes;
  12573. $this->class = $class;
  12574. $this->name = \is_string($name) ? new Identifier($name) : $name;
  12575. $this->args = $args;
  12576. }
  12577. public function getSubNodeNames(): array
  12578. {
  12579. return ['class', 'name', 'args'];
  12580. }
  12581. public function getType(): string
  12582. {
  12583. return 'Expr_StaticCall';
  12584. }
  12585. public function getRawArgs(): array
  12586. {
  12587. return $this->args;
  12588. }
  12589. }
  12590. <?php
  12591. declare (strict_types=1);
  12592. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12593. use PHPUnitPHAR\PhpParser\Node;
  12594. use PHPUnitPHAR\PhpParser\Node\Expr;
  12595. use PHPUnitPHAR\PhpParser\Node\Name;
  12596. use PHPUnitPHAR\PhpParser\Node\VarLikeIdentifier;
  12597. class StaticPropertyFetch extends Expr
  12598. {
  12599. /** @var Name|Expr Class name */
  12600. public Node $class;
  12601. /** @var VarLikeIdentifier|Expr Property name */
  12602. public Node $name;
  12603. /**
  12604. * Constructs a static property fetch node.
  12605. *
  12606. * @param Name|Expr $class Class name
  12607. * @param string|VarLikeIdentifier|Expr $name Property name
  12608. * @param array<string, mixed> $attributes Additional attributes
  12609. */
  12610. public function __construct(Node $class, $name, array $attributes = [])
  12611. {
  12612. $this->attributes = $attributes;
  12613. $this->class = $class;
  12614. $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name;
  12615. }
  12616. public function getSubNodeNames(): array
  12617. {
  12618. return ['class', 'name'];
  12619. }
  12620. public function getType(): string
  12621. {
  12622. return 'Expr_StaticPropertyFetch';
  12623. }
  12624. }
  12625. <?php
  12626. declare (strict_types=1);
  12627. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12628. use PHPUnitPHAR\PhpParser\Node\Expr;
  12629. class Ternary extends Expr
  12630. {
  12631. /** @var Expr Condition */
  12632. public Expr $cond;
  12633. /** @var null|Expr Expression for true */
  12634. public ?Expr $if;
  12635. /** @var Expr Expression for false */
  12636. public Expr $else;
  12637. /**
  12638. * Constructs a ternary operator node.
  12639. *
  12640. * @param Expr $cond Condition
  12641. * @param null|Expr $if Expression for true
  12642. * @param Expr $else Expression for false
  12643. * @param array<string, mixed> $attributes Additional attributes
  12644. */
  12645. public function __construct(Expr $cond, ?Expr $if, Expr $else, array $attributes = [])
  12646. {
  12647. $this->attributes = $attributes;
  12648. $this->cond = $cond;
  12649. $this->if = $if;
  12650. $this->else = $else;
  12651. }
  12652. public function getSubNodeNames(): array
  12653. {
  12654. return ['cond', 'if', 'else'];
  12655. }
  12656. public function getType(): string
  12657. {
  12658. return 'Expr_Ternary';
  12659. }
  12660. }
  12661. <?php
  12662. declare (strict_types=1);
  12663. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12664. use PHPUnitPHAR\PhpParser\Node;
  12665. class Throw_ extends Node\Expr
  12666. {
  12667. /** @var Node\Expr Expression */
  12668. public Node\Expr $expr;
  12669. /**
  12670. * Constructs a throw expression node.
  12671. *
  12672. * @param Node\Expr $expr Expression
  12673. * @param array<string, mixed> $attributes Additional attributes
  12674. */
  12675. public function __construct(Node\Expr $expr, array $attributes = [])
  12676. {
  12677. $this->attributes = $attributes;
  12678. $this->expr = $expr;
  12679. }
  12680. public function getSubNodeNames(): array
  12681. {
  12682. return ['expr'];
  12683. }
  12684. public function getType(): string
  12685. {
  12686. return 'Expr_Throw';
  12687. }
  12688. }
  12689. <?php
  12690. declare (strict_types=1);
  12691. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12692. use PHPUnitPHAR\PhpParser\Node\Expr;
  12693. class UnaryMinus extends Expr
  12694. {
  12695. /** @var Expr Expression */
  12696. public Expr $expr;
  12697. /**
  12698. * Constructs a unary minus node.
  12699. *
  12700. * @param Expr $expr Expression
  12701. * @param array<string, mixed> $attributes Additional attributes
  12702. */
  12703. public function __construct(Expr $expr, array $attributes = [])
  12704. {
  12705. $this->attributes = $attributes;
  12706. $this->expr = $expr;
  12707. }
  12708. public function getSubNodeNames(): array
  12709. {
  12710. return ['expr'];
  12711. }
  12712. public function getType(): string
  12713. {
  12714. return 'Expr_UnaryMinus';
  12715. }
  12716. }
  12717. <?php
  12718. declare (strict_types=1);
  12719. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12720. use PHPUnitPHAR\PhpParser\Node\Expr;
  12721. class UnaryPlus extends Expr
  12722. {
  12723. /** @var Expr Expression */
  12724. public Expr $expr;
  12725. /**
  12726. * Constructs a unary plus node.
  12727. *
  12728. * @param Expr $expr Expression
  12729. * @param array<string, mixed> $attributes Additional attributes
  12730. */
  12731. public function __construct(Expr $expr, array $attributes = [])
  12732. {
  12733. $this->attributes = $attributes;
  12734. $this->expr = $expr;
  12735. }
  12736. public function getSubNodeNames(): array
  12737. {
  12738. return ['expr'];
  12739. }
  12740. public function getType(): string
  12741. {
  12742. return 'Expr_UnaryPlus';
  12743. }
  12744. }
  12745. <?php
  12746. declare (strict_types=1);
  12747. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12748. use PHPUnitPHAR\PhpParser\Node\Expr;
  12749. class Variable extends Expr
  12750. {
  12751. /** @var string|Expr Name */
  12752. public $name;
  12753. /**
  12754. * Constructs a variable node.
  12755. *
  12756. * @param string|Expr $name Name
  12757. * @param array<string, mixed> $attributes Additional attributes
  12758. */
  12759. public function __construct($name, array $attributes = [])
  12760. {
  12761. $this->attributes = $attributes;
  12762. $this->name = $name;
  12763. }
  12764. public function getSubNodeNames(): array
  12765. {
  12766. return ['name'];
  12767. }
  12768. public function getType(): string
  12769. {
  12770. return 'Expr_Variable';
  12771. }
  12772. }
  12773. <?php
  12774. declare (strict_types=1);
  12775. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12776. use PHPUnitPHAR\PhpParser\Node\Expr;
  12777. class YieldFrom extends Expr
  12778. {
  12779. /** @var Expr Expression to yield from */
  12780. public Expr $expr;
  12781. /**
  12782. * Constructs an "yield from" node.
  12783. *
  12784. * @param Expr $expr Expression
  12785. * @param array<string, mixed> $attributes Additional attributes
  12786. */
  12787. public function __construct(Expr $expr, array $attributes = [])
  12788. {
  12789. $this->attributes = $attributes;
  12790. $this->expr = $expr;
  12791. }
  12792. public function getSubNodeNames(): array
  12793. {
  12794. return ['expr'];
  12795. }
  12796. public function getType(): string
  12797. {
  12798. return 'Expr_YieldFrom';
  12799. }
  12800. }
  12801. <?php
  12802. declare (strict_types=1);
  12803. namespace PHPUnitPHAR\PhpParser\Node\Expr;
  12804. use PHPUnitPHAR\PhpParser\Node\Expr;
  12805. class Yield_ extends Expr
  12806. {
  12807. /** @var null|Expr Key expression */
  12808. public ?Expr $key;
  12809. /** @var null|Expr Value expression */
  12810. public ?Expr $value;
  12811. /**
  12812. * Constructs a yield expression node.
  12813. *
  12814. * @param null|Expr $value Value expression
  12815. * @param null|Expr $key Key expression
  12816. * @param array<string, mixed> $attributes Additional attributes
  12817. */
  12818. public function __construct(?Expr $value = null, ?Expr $key = null, array $attributes = [])
  12819. {
  12820. $this->attributes = $attributes;
  12821. $this->key = $key;
  12822. $this->value = $value;
  12823. }
  12824. public function getSubNodeNames(): array
  12825. {
  12826. return ['key', 'value'];
  12827. }
  12828. public function getType(): string
  12829. {
  12830. return 'Expr_Yield';
  12831. }
  12832. }
  12833. <?php
  12834. declare (strict_types=1);
  12835. namespace PHPUnitPHAR\PhpParser\Node;
  12836. use PHPUnitPHAR\PhpParser\Node;
  12837. interface FunctionLike extends Node
  12838. {
  12839. /**
  12840. * Whether to return by reference
  12841. */
  12842. public function returnsByRef(): bool;
  12843. /**
  12844. * List of parameters
  12845. *
  12846. * @return Param[]
  12847. */
  12848. public function getParams(): array;
  12849. /**
  12850. * Get the declared return type or null
  12851. *
  12852. * @return null|Identifier|Name|ComplexType
  12853. */
  12854. public function getReturnType();
  12855. /**
  12856. * The function body
  12857. *
  12858. * @return Stmt[]|null
  12859. */
  12860. public function getStmts(): ?array;
  12861. /**
  12862. * Get PHP attribute groups.
  12863. *
  12864. * @return AttributeGroup[]
  12865. */
  12866. public function getAttrGroups(): array;
  12867. }
  12868. <?php
  12869. declare (strict_types=1);
  12870. namespace PHPUnitPHAR\PhpParser\Node;
  12871. use PHPUnitPHAR\PhpParser\NodeAbstract;
  12872. /**
  12873. * Represents a non-namespaced name. Namespaced names are represented using Name nodes.
  12874. */
  12875. class Identifier extends NodeAbstract
  12876. {
  12877. /**
  12878. * @psalm-var non-empty-string
  12879. * @var string Identifier as string
  12880. */
  12881. public string $name;
  12882. /** @var array<string, bool> */
  12883. private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
  12884. /**
  12885. * Constructs an identifier node.
  12886. *
  12887. * @param string $name Identifier as string
  12888. * @param array<string, mixed> $attributes Additional attributes
  12889. */
  12890. public function __construct(string $name, array $attributes = [])
  12891. {
  12892. if ($name === '') {
  12893. throw new \InvalidArgumentException('Identifier name cannot be empty');
  12894. }
  12895. $this->attributes = $attributes;
  12896. $this->name = $name;
  12897. }
  12898. public function getSubNodeNames(): array
  12899. {
  12900. return ['name'];
  12901. }
  12902. /**
  12903. * Get identifier as string.
  12904. *
  12905. * @psalm-return non-empty-string
  12906. * @return string Identifier as string.
  12907. */
  12908. public function toString(): string
  12909. {
  12910. return $this->name;
  12911. }
  12912. /**
  12913. * Get lowercased identifier as string.
  12914. *
  12915. * @psalm-return non-empty-string
  12916. * @return string Lowercased identifier as string
  12917. */
  12918. public function toLowerString(): string
  12919. {
  12920. return strtolower($this->name);
  12921. }
  12922. /**
  12923. * Checks whether the identifier is a special class name (self, parent or static).
  12924. *
  12925. * @return bool Whether identifier is a special class name
  12926. */
  12927. public function isSpecialClassName(): bool
  12928. {
  12929. return isset(self::$specialClassNames[strtolower($this->name)]);
  12930. }
  12931. /**
  12932. * Get identifier as string.
  12933. *
  12934. * @psalm-return non-empty-string
  12935. * @return string Identifier as string
  12936. */
  12937. public function __toString(): string
  12938. {
  12939. return $this->name;
  12940. }
  12941. public function getType(): string
  12942. {
  12943. return 'Identifier';
  12944. }
  12945. }
  12946. <?php
  12947. declare (strict_types=1);
  12948. namespace PHPUnitPHAR\PhpParser\Node;
  12949. use PHPUnitPHAR\PhpParser\NodeAbstract;
  12950. class InterpolatedStringPart extends NodeAbstract
  12951. {
  12952. /** @var string String value */
  12953. public string $value;
  12954. /**
  12955. * Constructs a node representing a string part of an interpolated string.
  12956. *
  12957. * @param string $value String value
  12958. * @param array<string, mixed> $attributes Additional attributes
  12959. */
  12960. public function __construct(string $value, array $attributes = [])
  12961. {
  12962. $this->attributes = $attributes;
  12963. $this->value = $value;
  12964. }
  12965. public function getSubNodeNames(): array
  12966. {
  12967. return ['value'];
  12968. }
  12969. public function getType(): string
  12970. {
  12971. return 'InterpolatedStringPart';
  12972. }
  12973. }
  12974. // @deprecated compatibility alias
  12975. class_alias(InterpolatedStringPart::class, Scalar\EncapsedStringPart::class);
  12976. <?php
  12977. declare (strict_types=1);
  12978. namespace PHPUnitPHAR\PhpParser\Node;
  12979. class IntersectionType extends ComplexType
  12980. {
  12981. /** @var (Identifier|Name)[] Types */
  12982. public array $types;
  12983. /**
  12984. * Constructs an intersection type.
  12985. *
  12986. * @param (Identifier|Name)[] $types Types
  12987. * @param array<string, mixed> $attributes Additional attributes
  12988. */
  12989. public function __construct(array $types, array $attributes = [])
  12990. {
  12991. $this->attributes = $attributes;
  12992. $this->types = $types;
  12993. }
  12994. public function getSubNodeNames(): array
  12995. {
  12996. return ['types'];
  12997. }
  12998. public function getType(): string
  12999. {
  13000. return 'IntersectionType';
  13001. }
  13002. }
  13003. <?php
  13004. declare (strict_types=1);
  13005. namespace PHPUnitPHAR\PhpParser\Node;
  13006. use PHPUnitPHAR\PhpParser\Node;
  13007. use PHPUnitPHAR\PhpParser\NodeAbstract;
  13008. class MatchArm extends NodeAbstract
  13009. {
  13010. /** @var null|list<Node\Expr> */
  13011. public ?array $conds;
  13012. /** @var Node\Expr */
  13013. public Expr $body;
  13014. /**
  13015. * @param null|list<Node\Expr> $conds
  13016. */
  13017. public function __construct(?array $conds, Node\Expr $body, array $attributes = [])
  13018. {
  13019. $this->conds = $conds;
  13020. $this->body = $body;
  13021. $this->attributes = $attributes;
  13022. }
  13023. public function getSubNodeNames(): array
  13024. {
  13025. return ['conds', 'body'];
  13026. }
  13027. public function getType(): string
  13028. {
  13029. return 'MatchArm';
  13030. }
  13031. }
  13032. <?php
  13033. declare (strict_types=1);
  13034. namespace PHPUnitPHAR\PhpParser\Node;
  13035. use PHPUnitPHAR\PhpParser\NodeAbstract;
  13036. class Name extends NodeAbstract
  13037. {
  13038. /**
  13039. * @psalm-var non-empty-string
  13040. * @var string Name as string
  13041. */
  13042. public string $name;
  13043. /** @var array<string, bool> */
  13044. private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
  13045. /**
  13046. * Constructs a name node.
  13047. *
  13048. * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor)
  13049. * @param array<string, mixed> $attributes Additional attributes
  13050. */
  13051. final public function __construct($name, array $attributes = [])
  13052. {
  13053. $this->attributes = $attributes;
  13054. $this->name = self::prepareName($name);
  13055. }
  13056. public function getSubNodeNames(): array
  13057. {
  13058. return ['name'];
  13059. }
  13060. /**
  13061. * Get parts of name (split by the namespace separator).
  13062. *
  13063. * @psalm-return non-empty-list<string>
  13064. * @return string[] Parts of name
  13065. */
  13066. public function getParts(): array
  13067. {
  13068. return \explode('\\', $this->name);
  13069. }
  13070. /**
  13071. * Gets the first part of the name, i.e. everything before the first namespace separator.
  13072. *
  13073. * @return string First part of the name
  13074. */
  13075. public function getFirst(): string
  13076. {
  13077. if (\false !== $pos = \strpos($this->name, '\\')) {
  13078. return \substr($this->name, 0, $pos);
  13079. }
  13080. return $this->name;
  13081. }
  13082. /**
  13083. * Gets the last part of the name, i.e. everything after the last namespace separator.
  13084. *
  13085. * @return string Last part of the name
  13086. */
  13087. public function getLast(): string
  13088. {
  13089. if (\false !== $pos = \strrpos($this->name, '\\')) {
  13090. return \substr($this->name, $pos + 1);
  13091. }
  13092. return $this->name;
  13093. }
  13094. /**
  13095. * Checks whether the name is unqualified. (E.g. Name)
  13096. *
  13097. * @return bool Whether the name is unqualified
  13098. */
  13099. public function isUnqualified(): bool
  13100. {
  13101. return \false === \strpos($this->name, '\\');
  13102. }
  13103. /**
  13104. * Checks whether the name is qualified. (E.g. Name\Name)
  13105. *
  13106. * @return bool Whether the name is qualified
  13107. */
  13108. public function isQualified(): bool
  13109. {
  13110. return \false !== \strpos($this->name, '\\');
  13111. }
  13112. /**
  13113. * Checks whether the name is fully qualified. (E.g. \Name)
  13114. *
  13115. * @return bool Whether the name is fully qualified
  13116. */
  13117. public function isFullyQualified(): bool
  13118. {
  13119. return \false;
  13120. }
  13121. /**
  13122. * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
  13123. *
  13124. * @return bool Whether the name is relative
  13125. */
  13126. public function isRelative(): bool
  13127. {
  13128. return \false;
  13129. }
  13130. /**
  13131. * Returns a string representation of the name itself, without taking the name type into
  13132. * account (e.g., not including a leading backslash for fully qualified names).
  13133. *
  13134. * @psalm-return non-empty-string
  13135. * @return string String representation
  13136. */
  13137. public function toString(): string
  13138. {
  13139. return $this->name;
  13140. }
  13141. /**
  13142. * Returns a string representation of the name as it would occur in code (e.g., including
  13143. * leading backslash for fully qualified names.
  13144. *
  13145. * @psalm-return non-empty-string
  13146. * @return string String representation
  13147. */
  13148. public function toCodeString(): string
  13149. {
  13150. return $this->toString();
  13151. }
  13152. /**
  13153. * Returns lowercased string representation of the name, without taking the name type into
  13154. * account (e.g., no leading backslash for fully qualified names).
  13155. *
  13156. * @psalm-return non-empty-string
  13157. * @return string Lowercased string representation
  13158. */
  13159. public function toLowerString(): string
  13160. {
  13161. return strtolower($this->name);
  13162. }
  13163. /**
  13164. * Checks whether the identifier is a special class name (self, parent or static).
  13165. *
  13166. * @return bool Whether identifier is a special class name
  13167. */
  13168. public function isSpecialClassName(): bool
  13169. {
  13170. return isset(self::$specialClassNames[strtolower($this->name)]);
  13171. }
  13172. /**
  13173. * Returns a string representation of the name by imploding the namespace parts with the
  13174. * namespace separator.
  13175. *
  13176. * @psalm-return non-empty-string
  13177. * @return string String representation
  13178. */
  13179. public function __toString(): string
  13180. {
  13181. return $this->name;
  13182. }
  13183. /**
  13184. * Gets a slice of a name (similar to array_slice).
  13185. *
  13186. * This method returns a new instance of the same type as the original and with the same
  13187. * attributes.
  13188. *
  13189. * If the slice is empty, null is returned. The null value will be correctly handled in
  13190. * concatenations using concat().
  13191. *
  13192. * Offset and length have the same meaning as in array_slice().
  13193. *
  13194. * @param int $offset Offset to start the slice at (may be negative)
  13195. * @param int|null $length Length of the slice (may be negative)
  13196. *
  13197. * @return static|null Sliced name
  13198. */
  13199. public function slice(int $offset, ?int $length = null)
  13200. {
  13201. if ($offset === 1 && $length === null) {
  13202. // Short-circuit the common case.
  13203. if (\false !== $pos = \strpos($this->name, '\\')) {
  13204. return new static(\substr($this->name, $pos + 1));
  13205. }
  13206. return null;
  13207. }
  13208. $parts = \explode('\\', $this->name);
  13209. $numParts = \count($parts);
  13210. $realOffset = $offset < 0 ? $offset + $numParts : $offset;
  13211. if ($realOffset < 0 || $realOffset > $numParts) {
  13212. throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
  13213. }
  13214. if (null === $length) {
  13215. $realLength = $numParts - $realOffset;
  13216. } else {
  13217. $realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
  13218. if ($realLength < 0 || $realLength > $numParts - $realOffset) {
  13219. throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length));
  13220. }
  13221. }
  13222. if ($realLength === 0) {
  13223. // Empty slice is represented as null
  13224. return null;
  13225. }
  13226. return new static(array_slice($parts, $realOffset, $realLength), $this->attributes);
  13227. }
  13228. /**
  13229. * Concatenate two names, yielding a new Name instance.
  13230. *
  13231. * The type of the generated instance depends on which class this method is called on, for
  13232. * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance.
  13233. *
  13234. * If one of the arguments is null, a new instance of the other name will be returned. If both
  13235. * arguments are null, null will be returned. As such, writing
  13236. * Name::concat($namespace, $shortName)
  13237. * where $namespace is a Name node or null will work as expected.
  13238. *
  13239. * @param string|string[]|self|null $name1 The first name
  13240. * @param string|string[]|self|null $name2 The second name
  13241. * @param array<string, mixed> $attributes Attributes to assign to concatenated name
  13242. *
  13243. * @return static|null Concatenated name
  13244. */
  13245. public static function concat($name1, $name2, array $attributes = [])
  13246. {
  13247. if (null === $name1 && null === $name2) {
  13248. return null;
  13249. }
  13250. if (null === $name1) {
  13251. return new static($name2, $attributes);
  13252. }
  13253. if (null === $name2) {
  13254. return new static($name1, $attributes);
  13255. } else {
  13256. return new static(self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes);
  13257. }
  13258. }
  13259. /**
  13260. * Prepares a (string, array or Name node) name for use in name changing methods by converting
  13261. * it to a string.
  13262. *
  13263. * @param string|string[]|self $name Name to prepare
  13264. *
  13265. * @psalm-return non-empty-string
  13266. * @return string Prepared name
  13267. */
  13268. private static function prepareName($name): string
  13269. {
  13270. if (\is_string($name)) {
  13271. if ('' === $name) {
  13272. throw new \InvalidArgumentException('Name cannot be empty');
  13273. }
  13274. return $name;
  13275. }
  13276. if (\is_array($name)) {
  13277. if (empty($name)) {
  13278. throw new \InvalidArgumentException('Name cannot be empty');
  13279. }
  13280. return implode('\\', $name);
  13281. }
  13282. if ($name instanceof self) {
  13283. return $name->name;
  13284. }
  13285. throw new \InvalidArgumentException('Expected string, array of parts or Name instance');
  13286. }
  13287. public function getType(): string
  13288. {
  13289. return 'Name';
  13290. }
  13291. }
  13292. <?php
  13293. declare (strict_types=1);
  13294. namespace PHPUnitPHAR\PhpParser\Node\Name;
  13295. class FullyQualified extends \PHPUnitPHAR\PhpParser\Node\Name
  13296. {
  13297. /**
  13298. * Checks whether the name is unqualified. (E.g. Name)
  13299. *
  13300. * @return bool Whether the name is unqualified
  13301. */
  13302. public function isUnqualified(): bool
  13303. {
  13304. return \false;
  13305. }
  13306. /**
  13307. * Checks whether the name is qualified. (E.g. Name\Name)
  13308. *
  13309. * @return bool Whether the name is qualified
  13310. */
  13311. public function isQualified(): bool
  13312. {
  13313. return \false;
  13314. }
  13315. /**
  13316. * Checks whether the name is fully qualified. (E.g. \Name)
  13317. *
  13318. * @return bool Whether the name is fully qualified
  13319. */
  13320. public function isFullyQualified(): bool
  13321. {
  13322. return \true;
  13323. }
  13324. /**
  13325. * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
  13326. *
  13327. * @return bool Whether the name is relative
  13328. */
  13329. public function isRelative(): bool
  13330. {
  13331. return \false;
  13332. }
  13333. public function toCodeString(): string
  13334. {
  13335. return '\\' . $this->toString();
  13336. }
  13337. public function getType(): string
  13338. {
  13339. return 'Name_FullyQualified';
  13340. }
  13341. }
  13342. <?php
  13343. declare (strict_types=1);
  13344. namespace PHPUnitPHAR\PhpParser\Node\Name;
  13345. class Relative extends \PHPUnitPHAR\PhpParser\Node\Name
  13346. {
  13347. /**
  13348. * Checks whether the name is unqualified. (E.g. Name)
  13349. *
  13350. * @return bool Whether the name is unqualified
  13351. */
  13352. public function isUnqualified(): bool
  13353. {
  13354. return \false;
  13355. }
  13356. /**
  13357. * Checks whether the name is qualified. (E.g. Name\Name)
  13358. *
  13359. * @return bool Whether the name is qualified
  13360. */
  13361. public function isQualified(): bool
  13362. {
  13363. return \false;
  13364. }
  13365. /**
  13366. * Checks whether the name is fully qualified. (E.g. \Name)
  13367. *
  13368. * @return bool Whether the name is fully qualified
  13369. */
  13370. public function isFullyQualified(): bool
  13371. {
  13372. return \false;
  13373. }
  13374. /**
  13375. * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
  13376. *
  13377. * @return bool Whether the name is relative
  13378. */
  13379. public function isRelative(): bool
  13380. {
  13381. return \true;
  13382. }
  13383. public function toCodeString(): string
  13384. {
  13385. return 'namespace\\' . $this->toString();
  13386. }
  13387. public function getType(): string
  13388. {
  13389. return 'Name_Relative';
  13390. }
  13391. }
  13392. <?php
  13393. declare (strict_types=1);
  13394. namespace PHPUnitPHAR\PhpParser\Node;
  13395. use PHPUnitPHAR\PhpParser\Node;
  13396. class NullableType extends ComplexType
  13397. {
  13398. /** @var Identifier|Name Type */
  13399. public Node $type;
  13400. /**
  13401. * Constructs a nullable type (wrapping another type).
  13402. *
  13403. * @param Identifier|Name $type Type
  13404. * @param array<string, mixed> $attributes Additional attributes
  13405. */
  13406. public function __construct(Node $type, array $attributes = [])
  13407. {
  13408. $this->attributes = $attributes;
  13409. $this->type = $type;
  13410. }
  13411. public function getSubNodeNames(): array
  13412. {
  13413. return ['type'];
  13414. }
  13415. public function getType(): string
  13416. {
  13417. return 'NullableType';
  13418. }
  13419. }
  13420. <?php
  13421. declare (strict_types=1);
  13422. namespace PHPUnitPHAR\PhpParser\Node;
  13423. use PHPUnitPHAR\PhpParser\Modifiers;
  13424. use PHPUnitPHAR\PhpParser\Node;
  13425. use PHPUnitPHAR\PhpParser\NodeAbstract;
  13426. class Param extends NodeAbstract
  13427. {
  13428. /** @var null|Identifier|Name|ComplexType Type declaration */
  13429. public ?Node $type;
  13430. /** @var bool Whether parameter is passed by reference */
  13431. public bool $byRef;
  13432. /** @var bool Whether this is a variadic argument */
  13433. public bool $variadic;
  13434. /** @var Expr\Variable|Expr\Error Parameter variable */
  13435. public Expr $var;
  13436. /** @var null|Expr Default value */
  13437. public ?Expr $default;
  13438. /** @var int Optional visibility flags */
  13439. public int $flags;
  13440. /** @var AttributeGroup[] PHP attribute groups */
  13441. public array $attrGroups;
  13442. /** @var PropertyHook[] Property hooks for promoted properties */
  13443. public array $hooks;
  13444. /**
  13445. * Constructs a parameter node.
  13446. *
  13447. * @param Expr\Variable|Expr\Error $var Parameter variable
  13448. * @param null|Expr $default Default value
  13449. * @param null|Identifier|Name|ComplexType $type Type declaration
  13450. * @param bool $byRef Whether is passed by reference
  13451. * @param bool $variadic Whether this is a variadic argument
  13452. * @param array<string, mixed> $attributes Additional attributes
  13453. * @param int $flags Optional visibility flags
  13454. * @param list<AttributeGroup> $attrGroups PHP attribute groups
  13455. * @param PropertyHook[] $hooks Property hooks for promoted properties
  13456. */
  13457. public function __construct(Expr $var, ?Expr $default = null, ?Node $type = null, bool $byRef = \false, bool $variadic = \false, array $attributes = [], int $flags = 0, array $attrGroups = [], array $hooks = [])
  13458. {
  13459. $this->attributes = $attributes;
  13460. $this->type = $type;
  13461. $this->byRef = $byRef;
  13462. $this->variadic = $variadic;
  13463. $this->var = $var;
  13464. $this->default = $default;
  13465. $this->flags = $flags;
  13466. $this->attrGroups = $attrGroups;
  13467. $this->hooks = $hooks;
  13468. }
  13469. public function getSubNodeNames(): array
  13470. {
  13471. return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default', 'hooks'];
  13472. }
  13473. public function getType(): string
  13474. {
  13475. return 'Param';
  13476. }
  13477. /**
  13478. * Whether this parameter uses constructor property promotion.
  13479. */
  13480. public function isPromoted(): bool
  13481. {
  13482. return $this->flags !== 0;
  13483. }
  13484. public function isPublic(): bool
  13485. {
  13486. return (bool) ($this->flags & Modifiers::PUBLIC);
  13487. }
  13488. public function isProtected(): bool
  13489. {
  13490. return (bool) ($this->flags & Modifiers::PROTECTED);
  13491. }
  13492. public function isPrivate(): bool
  13493. {
  13494. return (bool) ($this->flags & Modifiers::PRIVATE);
  13495. }
  13496. public function isReadonly(): bool
  13497. {
  13498. return (bool) ($this->flags & Modifiers::READONLY);
  13499. }
  13500. /**
  13501. * Whether the promoted property has explicit public(set) visibility.
  13502. */
  13503. public function isPublicSet(): bool
  13504. {
  13505. return (bool) ($this->flags & Modifiers::PUBLIC_SET);
  13506. }
  13507. /**
  13508. * Whether the promoted property has explicit protected(set) visibility.
  13509. */
  13510. public function isProtectedSet(): bool
  13511. {
  13512. return (bool) ($this->flags & Modifiers::PROTECTED_SET);
  13513. }
  13514. /**
  13515. * Whether the promoted property has explicit private(set) visibility.
  13516. */
  13517. public function isPrivateSet(): bool
  13518. {
  13519. return (bool) ($this->flags & Modifiers::PRIVATE_SET);
  13520. }
  13521. }
  13522. <?php
  13523. declare (strict_types=1);
  13524. namespace PHPUnitPHAR\PhpParser\Node;
  13525. use PHPUnitPHAR\PhpParser\Node\Stmt\Return_;
  13526. use PHPUnitPHAR\PhpParser\NodeAbstract;
  13527. class PropertyHook extends NodeAbstract implements FunctionLike
  13528. {
  13529. /** @var AttributeGroup[] PHP attribute groups */
  13530. public array $attrGroups;
  13531. /** @var int Modifiers */
  13532. public int $flags;
  13533. /** @var bool Whether hook returns by reference */
  13534. public bool $byRef;
  13535. /** @var Identifier Hook name */
  13536. public Identifier $name;
  13537. /** @var Param[] Parameters */
  13538. public array $params;
  13539. /** @var null|Expr|Stmt[] Hook body */
  13540. public $body;
  13541. /**
  13542. * Constructs a property hook node.
  13543. *
  13544. * @param string|Identifier $name Hook name
  13545. * @param null|Expr|Stmt[] $body Hook body
  13546. * @param array{
  13547. * flags?: int,
  13548. * byRef?: bool,
  13549. * params?: Param[],
  13550. * attrGroups?: AttributeGroup[],
  13551. * } $subNodes Array of the following optional subnodes:
  13552. * 'byRef' => false : Whether hook returns by reference
  13553. * 'params' => array(): Parameters
  13554. * 'attrGroups' => array(): PHP attribute groups
  13555. * @param array<string, mixed> $attributes Additional attributes
  13556. */
  13557. public function __construct($name, $body, array $subNodes = [], array $attributes = [])
  13558. {
  13559. $this->attributes = $attributes;
  13560. $this->name = \is_string($name) ? new Identifier($name) : $name;
  13561. $this->body = $body;
  13562. $this->flags = $subNodes['flags'] ?? 0;
  13563. $this->byRef = $subNodes['byRef'] ?? \false;
  13564. $this->params = $subNodes['params'] ?? [];
  13565. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  13566. }
  13567. public function returnsByRef(): bool
  13568. {
  13569. return $this->byRef;
  13570. }
  13571. public function getParams(): array
  13572. {
  13573. return $this->params;
  13574. }
  13575. public function getReturnType()
  13576. {
  13577. return null;
  13578. }
  13579. public function getStmts(): ?array
  13580. {
  13581. if ($this->body instanceof Expr) {
  13582. return [new Return_($this->body)];
  13583. }
  13584. return $this->body;
  13585. }
  13586. public function getAttrGroups(): array
  13587. {
  13588. return $this->attrGroups;
  13589. }
  13590. public function getType(): string
  13591. {
  13592. return 'PropertyHook';
  13593. }
  13594. public function getSubNodeNames(): array
  13595. {
  13596. return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'body'];
  13597. }
  13598. }
  13599. <?php
  13600. declare (strict_types=1);
  13601. namespace PHPUnitPHAR\PhpParser\Node;
  13602. use PHPUnitPHAR\PhpParser\Node;
  13603. use PHPUnitPHAR\PhpParser\NodeAbstract;
  13604. class PropertyItem extends NodeAbstract
  13605. {
  13606. /** @var Node\VarLikeIdentifier Name */
  13607. public VarLikeIdentifier $name;
  13608. /** @var null|Node\Expr Default */
  13609. public ?Expr $default;
  13610. /**
  13611. * Constructs a class property item node.
  13612. *
  13613. * @param string|Node\VarLikeIdentifier $name Name
  13614. * @param null|Node\Expr $default Default value
  13615. * @param array<string, mixed> $attributes Additional attributes
  13616. */
  13617. public function __construct($name, ?Node\Expr $default = null, array $attributes = [])
  13618. {
  13619. $this->attributes = $attributes;
  13620. $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name;
  13621. $this->default = $default;
  13622. }
  13623. public function getSubNodeNames(): array
  13624. {
  13625. return ['name', 'default'];
  13626. }
  13627. public function getType(): string
  13628. {
  13629. return 'PropertyItem';
  13630. }
  13631. }
  13632. // @deprecated compatibility alias
  13633. class_alias(PropertyItem::class, Stmt\PropertyProperty::class);
  13634. <?php
  13635. declare (strict_types=1);
  13636. namespace PHPUnitPHAR\PhpParser\Node;
  13637. abstract class Scalar extends Expr
  13638. {
  13639. }
  13640. <?php
  13641. declare (strict_types=1);
  13642. namespace PHPUnitPHAR;
  13643. require __DIR__ . '/Float_.php';
  13644. <?php
  13645. declare (strict_types=1);
  13646. namespace PHPUnitPHAR;
  13647. require __DIR__ . '/InterpolatedString.php';
  13648. <?php
  13649. declare (strict_types=1);
  13650. namespace PHPUnitPHAR;
  13651. require __DIR__ . '/../InterpolatedStringPart.php';
  13652. <?php
  13653. declare (strict_types=1);
  13654. namespace PHPUnitPHAR\PhpParser\Node\Scalar;
  13655. use PHPUnitPHAR\PhpParser\Node\Scalar;
  13656. class Float_ extends Scalar
  13657. {
  13658. /** @var float Number value */
  13659. public float $value;
  13660. /**
  13661. * Constructs a float number scalar node.
  13662. *
  13663. * @param float $value Value of the number
  13664. * @param array<string, mixed> $attributes Additional attributes
  13665. */
  13666. public function __construct(float $value, array $attributes = [])
  13667. {
  13668. $this->attributes = $attributes;
  13669. $this->value = $value;
  13670. }
  13671. public function getSubNodeNames(): array
  13672. {
  13673. return ['value'];
  13674. }
  13675. /**
  13676. * @param mixed[] $attributes
  13677. */
  13678. public static function fromString(string $str, array $attributes = []): Float_
  13679. {
  13680. $attributes['rawValue'] = $str;
  13681. $float = self::parse($str);
  13682. return new Float_($float, $attributes);
  13683. }
  13684. /**
  13685. * @internal
  13686. *
  13687. * Parses a DNUMBER token like PHP would.
  13688. *
  13689. * @param string $str A string number
  13690. *
  13691. * @return float The parsed number
  13692. */
  13693. public static function parse(string $str): float
  13694. {
  13695. $str = str_replace('_', '', $str);
  13696. // Check whether this is one of the special integer notations.
  13697. if ('0' === $str[0]) {
  13698. // hex
  13699. if ('x' === $str[1] || 'X' === $str[1]) {
  13700. return hexdec($str);
  13701. }
  13702. // bin
  13703. if ('b' === $str[1] || 'B' === $str[1]) {
  13704. return bindec($str);
  13705. }
  13706. // oct, but only if the string does not contain any of '.eE'.
  13707. if (\false === strpbrk($str, '.eE')) {
  13708. // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit
  13709. // (8 or 9) so that only the digits before that are used.
  13710. return octdec(substr($str, 0, strcspn($str, '89')));
  13711. }
  13712. }
  13713. // dec
  13714. return (float) $str;
  13715. }
  13716. public function getType(): string
  13717. {
  13718. return 'Scalar_Float';
  13719. }
  13720. }
  13721. // @deprecated compatibility alias
  13722. class_alias(Float_::class, DNumber::class);
  13723. <?php
  13724. declare (strict_types=1);
  13725. namespace PHPUnitPHAR\PhpParser\Node\Scalar;
  13726. use PHPUnitPHAR\PhpParser\Error;
  13727. use PHPUnitPHAR\PhpParser\Node\Scalar;
  13728. class Int_ extends Scalar
  13729. {
  13730. /* For use in "kind" attribute */
  13731. public const KIND_BIN = 2;
  13732. public const KIND_OCT = 8;
  13733. public const KIND_DEC = 10;
  13734. public const KIND_HEX = 16;
  13735. /** @var int Number value */
  13736. public int $value;
  13737. /**
  13738. * Constructs an integer number scalar node.
  13739. *
  13740. * @param int $value Value of the number
  13741. * @param array<string, mixed> $attributes Additional attributes
  13742. */
  13743. public function __construct(int $value, array $attributes = [])
  13744. {
  13745. $this->attributes = $attributes;
  13746. $this->value = $value;
  13747. }
  13748. public function getSubNodeNames(): array
  13749. {
  13750. return ['value'];
  13751. }
  13752. /**
  13753. * Constructs an Int node from a string number literal.
  13754. *
  13755. * @param string $str String number literal (decimal, octal, hex or binary)
  13756. * @param array<string, mixed> $attributes Additional attributes
  13757. * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5)
  13758. *
  13759. * @return Int_ The constructed LNumber, including kind attribute
  13760. */
  13761. public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = \false): Int_
  13762. {
  13763. $attributes['rawValue'] = $str;
  13764. $str = str_replace('_', '', $str);
  13765. if ('0' !== $str[0] || '0' === $str) {
  13766. $attributes['kind'] = Int_::KIND_DEC;
  13767. return new Int_((int) $str, $attributes);
  13768. }
  13769. if ('x' === $str[1] || 'X' === $str[1]) {
  13770. $attributes['kind'] = Int_::KIND_HEX;
  13771. return new Int_(hexdec($str), $attributes);
  13772. }
  13773. if ('b' === $str[1] || 'B' === $str[1]) {
  13774. $attributes['kind'] = Int_::KIND_BIN;
  13775. return new Int_(bindec($str), $attributes);
  13776. }
  13777. if (!$allowInvalidOctal && strpbrk($str, '89')) {
  13778. throw new Error('Invalid numeric literal', $attributes);
  13779. }
  13780. // Strip optional explicit octal prefix.
  13781. if ('o' === $str[1] || 'O' === $str[1]) {
  13782. $str = substr($str, 2);
  13783. }
  13784. // use intval instead of octdec to get proper cutting behavior with malformed numbers
  13785. $attributes['kind'] = Int_::KIND_OCT;
  13786. return new Int_(intval($str, 8), $attributes);
  13787. }
  13788. public function getType(): string
  13789. {
  13790. return 'Scalar_Int';
  13791. }
  13792. }
  13793. // @deprecated compatibility alias
  13794. class_alias(Int_::class, LNumber::class);
  13795. <?php
  13796. declare (strict_types=1);
  13797. namespace PHPUnitPHAR\PhpParser\Node\Scalar;
  13798. use PHPUnitPHAR\PhpParser\Node\Expr;
  13799. use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
  13800. use PHPUnitPHAR\PhpParser\Node\Scalar;
  13801. class InterpolatedString extends Scalar
  13802. {
  13803. /** @var (Expr|InterpolatedStringPart)[] list of string parts */
  13804. public array $parts;
  13805. /**
  13806. * Constructs an interpolated string node.
  13807. *
  13808. * @param (Expr|InterpolatedStringPart)[] $parts Interpolated string parts
  13809. * @param array<string, mixed> $attributes Additional attributes
  13810. */
  13811. public function __construct(array $parts, array $attributes = [])
  13812. {
  13813. $this->attributes = $attributes;
  13814. $this->parts = $parts;
  13815. }
  13816. public function getSubNodeNames(): array
  13817. {
  13818. return ['parts'];
  13819. }
  13820. public function getType(): string
  13821. {
  13822. return 'Scalar_InterpolatedString';
  13823. }
  13824. }
  13825. // @deprecated compatibility alias
  13826. class_alias(InterpolatedString::class, Encapsed::class);
  13827. <?php
  13828. declare (strict_types=1);
  13829. namespace PHPUnitPHAR;
  13830. require __DIR__ . '/Int_.php';
  13831. <?php
  13832. declare (strict_types=1);
  13833. namespace PHPUnitPHAR\PhpParser\Node\Scalar;
  13834. use PHPUnitPHAR\PhpParser\Node\Scalar;
  13835. abstract class MagicConst extends Scalar
  13836. {
  13837. /**
  13838. * Constructs a magic constant node.
  13839. *
  13840. * @param array<string, mixed> $attributes Additional attributes
  13841. */
  13842. public function __construct(array $attributes = [])
  13843. {
  13844. $this->attributes = $attributes;
  13845. }
  13846. public function getSubNodeNames(): array
  13847. {
  13848. return [];
  13849. }
  13850. /**
  13851. * Get name of magic constant.
  13852. *
  13853. * @return string Name of magic constant
  13854. */
  13855. abstract public function getName(): string;
  13856. }
  13857. <?php
  13858. declare (strict_types=1);
  13859. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13860. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13861. class Class_ extends MagicConst
  13862. {
  13863. public function getName(): string
  13864. {
  13865. return '__CLASS__';
  13866. }
  13867. public function getType(): string
  13868. {
  13869. return 'Scalar_MagicConst_Class';
  13870. }
  13871. }
  13872. <?php
  13873. declare (strict_types=1);
  13874. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13875. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13876. class Dir extends MagicConst
  13877. {
  13878. public function getName(): string
  13879. {
  13880. return '__DIR__';
  13881. }
  13882. public function getType(): string
  13883. {
  13884. return 'Scalar_MagicConst_Dir';
  13885. }
  13886. }
  13887. <?php
  13888. declare (strict_types=1);
  13889. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13890. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13891. class File extends MagicConst
  13892. {
  13893. public function getName(): string
  13894. {
  13895. return '__FILE__';
  13896. }
  13897. public function getType(): string
  13898. {
  13899. return 'Scalar_MagicConst_File';
  13900. }
  13901. }
  13902. <?php
  13903. declare (strict_types=1);
  13904. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13905. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13906. class Function_ extends MagicConst
  13907. {
  13908. public function getName(): string
  13909. {
  13910. return '__FUNCTION__';
  13911. }
  13912. public function getType(): string
  13913. {
  13914. return 'Scalar_MagicConst_Function';
  13915. }
  13916. }
  13917. <?php
  13918. declare (strict_types=1);
  13919. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13920. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13921. class Line extends MagicConst
  13922. {
  13923. public function getName(): string
  13924. {
  13925. return '__LINE__';
  13926. }
  13927. public function getType(): string
  13928. {
  13929. return 'Scalar_MagicConst_Line';
  13930. }
  13931. }
  13932. <?php
  13933. declare (strict_types=1);
  13934. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13935. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13936. class Method extends MagicConst
  13937. {
  13938. public function getName(): string
  13939. {
  13940. return '__METHOD__';
  13941. }
  13942. public function getType(): string
  13943. {
  13944. return 'Scalar_MagicConst_Method';
  13945. }
  13946. }
  13947. <?php
  13948. declare (strict_types=1);
  13949. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13950. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13951. class Namespace_ extends MagicConst
  13952. {
  13953. public function getName(): string
  13954. {
  13955. return '__NAMESPACE__';
  13956. }
  13957. public function getType(): string
  13958. {
  13959. return 'Scalar_MagicConst_Namespace';
  13960. }
  13961. }
  13962. <?php
  13963. declare (strict_types=1);
  13964. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13965. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13966. class Property extends MagicConst
  13967. {
  13968. public function getName(): string
  13969. {
  13970. return '__PROPERTY__';
  13971. }
  13972. public function getType(): string
  13973. {
  13974. return 'Scalar_MagicConst_Property';
  13975. }
  13976. }
  13977. <?php
  13978. declare (strict_types=1);
  13979. namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13980. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  13981. class Trait_ extends MagicConst
  13982. {
  13983. public function getName(): string
  13984. {
  13985. return '__TRAIT__';
  13986. }
  13987. public function getType(): string
  13988. {
  13989. return 'Scalar_MagicConst_Trait';
  13990. }
  13991. }
  13992. <?php
  13993. declare (strict_types=1);
  13994. namespace PHPUnitPHAR\PhpParser\Node\Scalar;
  13995. use PHPUnitPHAR\PhpParser\Error;
  13996. use PHPUnitPHAR\PhpParser\Node\Scalar;
  13997. class String_ extends Scalar
  13998. {
  13999. /* For use in "kind" attribute */
  14000. public const KIND_SINGLE_QUOTED = 1;
  14001. public const KIND_DOUBLE_QUOTED = 2;
  14002. public const KIND_HEREDOC = 3;
  14003. public const KIND_NOWDOC = 4;
  14004. /** @var string String value */
  14005. public string $value;
  14006. /** @var array<string, string> Escaped character to its decoded value */
  14007. protected static array $replacements = ['\\' => '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1b"];
  14008. /**
  14009. * Constructs a string scalar node.
  14010. *
  14011. * @param string $value Value of the string
  14012. * @param array<string, mixed> $attributes Additional attributes
  14013. */
  14014. public function __construct(string $value, array $attributes = [])
  14015. {
  14016. $this->attributes = $attributes;
  14017. $this->value = $value;
  14018. }
  14019. public function getSubNodeNames(): array
  14020. {
  14021. return ['value'];
  14022. }
  14023. /**
  14024. * @param array<string, mixed> $attributes
  14025. * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
  14026. */
  14027. public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = \true): self
  14028. {
  14029. $attributes['kind'] = $str[0] === "'" || $str[1] === "'" && ($str[0] === 'b' || $str[0] === 'B') ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED;
  14030. $attributes['rawValue'] = $str;
  14031. $string = self::parse($str, $parseUnicodeEscape);
  14032. return new self($string, $attributes);
  14033. }
  14034. /**
  14035. * @internal
  14036. *
  14037. * Parses a string token.
  14038. *
  14039. * @param string $str String token content
  14040. * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
  14041. *
  14042. * @return string The parsed string
  14043. */
  14044. public static function parse(string $str, bool $parseUnicodeEscape = \true): string
  14045. {
  14046. $bLength = 0;
  14047. if ('b' === $str[0] || 'B' === $str[0]) {
  14048. $bLength = 1;
  14049. }
  14050. if ('\'' === $str[$bLength]) {
  14051. return str_replace(['\\\\', '\\\''], ['\\', '\''], substr($str, $bLength + 1, -1));
  14052. } else {
  14053. return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape);
  14054. }
  14055. }
  14056. /**
  14057. * @internal
  14058. *
  14059. * Parses escape sequences in strings (all string types apart from single quoted).
  14060. *
  14061. * @param string $str String without quotes
  14062. * @param null|string $quote Quote type
  14063. * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
  14064. *
  14065. * @return string String with escape sequences parsed
  14066. */
  14067. public static function parseEscapeSequences(string $str, ?string $quote, bool $parseUnicodeEscape = \true): string
  14068. {
  14069. if (null !== $quote) {
  14070. $str = str_replace('\\' . $quote, $quote, $str);
  14071. }
  14072. $extra = '';
  14073. if ($parseUnicodeEscape) {
  14074. $extra = '|u\{([0-9a-fA-F]+)\}';
  14075. }
  14076. return preg_replace_callback('~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', function ($matches) {
  14077. $str = $matches[1];
  14078. if (isset(self::$replacements[$str])) {
  14079. return self::$replacements[$str];
  14080. }
  14081. if ('x' === $str[0] || 'X' === $str[0]) {
  14082. return chr(hexdec(substr($str, 1)));
  14083. }
  14084. if ('u' === $str[0]) {
  14085. $dec = hexdec($matches[2]);
  14086. // If it overflowed to float, treat as INT_MAX, it will throw an error anyway.
  14087. return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX);
  14088. } else {
  14089. return chr(octdec($str));
  14090. }
  14091. }, $str);
  14092. }
  14093. /**
  14094. * Converts a Unicode code point to its UTF-8 encoded representation.
  14095. *
  14096. * @param int $num Code point
  14097. *
  14098. * @return string UTF-8 representation of code point
  14099. */
  14100. private static function codePointToUtf8(int $num): string
  14101. {
  14102. if ($num <= 0x7f) {
  14103. return chr($num);
  14104. }
  14105. if ($num <= 0x7ff) {
  14106. return chr(($num >> 6) + 0xc0) . chr(($num & 0x3f) + 0x80);
  14107. }
  14108. if ($num <= 0xffff) {
  14109. return chr(($num >> 12) + 0xe0) . chr(($num >> 6 & 0x3f) + 0x80) . chr(($num & 0x3f) + 0x80);
  14110. }
  14111. if ($num <= 0x1fffff) {
  14112. return chr(($num >> 18) + 0xf0) . chr(($num >> 12 & 0x3f) + 0x80) . chr(($num >> 6 & 0x3f) + 0x80) . chr(($num & 0x3f) + 0x80);
  14113. }
  14114. throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large');
  14115. }
  14116. public function getType(): string
  14117. {
  14118. return 'Scalar_String';
  14119. }
  14120. }
  14121. <?php
  14122. declare (strict_types=1);
  14123. namespace PHPUnitPHAR\PhpParser\Node;
  14124. use PHPUnitPHAR\PhpParser\Node;
  14125. use PHPUnitPHAR\PhpParser\NodeAbstract;
  14126. class StaticVar extends NodeAbstract
  14127. {
  14128. /** @var Expr\Variable Variable */
  14129. public Expr\Variable $var;
  14130. /** @var null|Node\Expr Default value */
  14131. public ?Expr $default;
  14132. /**
  14133. * Constructs a static variable node.
  14134. *
  14135. * @param Expr\Variable $var Name
  14136. * @param null|Node\Expr $default Default value
  14137. * @param array<string, mixed> $attributes Additional attributes
  14138. */
  14139. public function __construct(Expr\Variable $var, ?Node\Expr $default = null, array $attributes = [])
  14140. {
  14141. $this->attributes = $attributes;
  14142. $this->var = $var;
  14143. $this->default = $default;
  14144. }
  14145. public function getSubNodeNames(): array
  14146. {
  14147. return ['var', 'default'];
  14148. }
  14149. public function getType(): string
  14150. {
  14151. return 'StaticVar';
  14152. }
  14153. }
  14154. // @deprecated compatibility alias
  14155. class_alias(StaticVar::class, Stmt\StaticVar::class);
  14156. <?php
  14157. declare (strict_types=1);
  14158. namespace PHPUnitPHAR\PhpParser\Node;
  14159. use PHPUnitPHAR\PhpParser\NodeAbstract;
  14160. abstract class Stmt extends NodeAbstract
  14161. {
  14162. }
  14163. <?php
  14164. declare (strict_types=1);
  14165. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14166. use PHPUnitPHAR\PhpParser\Node\Stmt;
  14167. class Block extends Stmt
  14168. {
  14169. /** @var Stmt[] Statements */
  14170. public array $stmts;
  14171. /**
  14172. * A block of statements.
  14173. *
  14174. * @param Stmt[] $stmts Statements
  14175. * @param array<string, mixed> $attributes Additional attributes
  14176. */
  14177. public function __construct(array $stmts, array $attributes = [])
  14178. {
  14179. $this->attributes = $attributes;
  14180. $this->stmts = $stmts;
  14181. }
  14182. public function getType(): string
  14183. {
  14184. return 'Stmt_Block';
  14185. }
  14186. public function getSubNodeNames(): array
  14187. {
  14188. return ['stmts'];
  14189. }
  14190. }
  14191. <?php
  14192. declare (strict_types=1);
  14193. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14194. use PHPUnitPHAR\PhpParser\Node;
  14195. class Break_ extends Node\Stmt
  14196. {
  14197. /** @var null|Node\Expr Number of loops to break */
  14198. public ?Node\Expr $num;
  14199. /**
  14200. * Constructs a break node.
  14201. *
  14202. * @param null|Node\Expr $num Number of loops to break
  14203. * @param array<string, mixed> $attributes Additional attributes
  14204. */
  14205. public function __construct(?Node\Expr $num = null, array $attributes = [])
  14206. {
  14207. $this->attributes = $attributes;
  14208. $this->num = $num;
  14209. }
  14210. public function getSubNodeNames(): array
  14211. {
  14212. return ['num'];
  14213. }
  14214. public function getType(): string
  14215. {
  14216. return 'Stmt_Break';
  14217. }
  14218. }
  14219. <?php
  14220. declare (strict_types=1);
  14221. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14222. use PHPUnitPHAR\PhpParser\Node;
  14223. class Case_ extends Node\Stmt
  14224. {
  14225. /** @var null|Node\Expr Condition (null for default) */
  14226. public ?Node\Expr $cond;
  14227. /** @var Node\Stmt[] Statements */
  14228. public array $stmts;
  14229. /**
  14230. * Constructs a case node.
  14231. *
  14232. * @param null|Node\Expr $cond Condition (null for default)
  14233. * @param Node\Stmt[] $stmts Statements
  14234. * @param array<string, mixed> $attributes Additional attributes
  14235. */
  14236. public function __construct(?Node\Expr $cond, array $stmts = [], array $attributes = [])
  14237. {
  14238. $this->attributes = $attributes;
  14239. $this->cond = $cond;
  14240. $this->stmts = $stmts;
  14241. }
  14242. public function getSubNodeNames(): array
  14243. {
  14244. return ['cond', 'stmts'];
  14245. }
  14246. public function getType(): string
  14247. {
  14248. return 'Stmt_Case';
  14249. }
  14250. }
  14251. <?php
  14252. declare (strict_types=1);
  14253. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14254. use PHPUnitPHAR\PhpParser\Node;
  14255. use PHPUnitPHAR\PhpParser\Node\Expr;
  14256. class Catch_ extends Node\Stmt
  14257. {
  14258. /** @var Node\Name[] Types of exceptions to catch */
  14259. public array $types;
  14260. /** @var Expr\Variable|null Variable for exception */
  14261. public ?Expr\Variable $var;
  14262. /** @var Node\Stmt[] Statements */
  14263. public array $stmts;
  14264. /**
  14265. * Constructs a catch node.
  14266. *
  14267. * @param Node\Name[] $types Types of exceptions to catch
  14268. * @param Expr\Variable|null $var Variable for exception
  14269. * @param Node\Stmt[] $stmts Statements
  14270. * @param array<string, mixed> $attributes Additional attributes
  14271. */
  14272. public function __construct(array $types, ?Expr\Variable $var = null, array $stmts = [], array $attributes = [])
  14273. {
  14274. $this->attributes = $attributes;
  14275. $this->types = $types;
  14276. $this->var = $var;
  14277. $this->stmts = $stmts;
  14278. }
  14279. public function getSubNodeNames(): array
  14280. {
  14281. return ['types', 'var', 'stmts'];
  14282. }
  14283. public function getType(): string
  14284. {
  14285. return 'Stmt_Catch';
  14286. }
  14287. }
  14288. <?php
  14289. declare (strict_types=1);
  14290. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14291. use PHPUnitPHAR\PhpParser\Modifiers;
  14292. use PHPUnitPHAR\PhpParser\Node;
  14293. class ClassConst extends Node\Stmt
  14294. {
  14295. /** @var int Modifiers */
  14296. public int $flags;
  14297. /** @var Node\Const_[] Constant declarations */
  14298. public array $consts;
  14299. /** @var Node\AttributeGroup[] PHP attribute groups */
  14300. public array $attrGroups;
  14301. /** @var Node\Identifier|Node\Name|Node\ComplexType|null Type declaration */
  14302. public ?Node $type;
  14303. /**
  14304. * Constructs a class const list node.
  14305. *
  14306. * @param Node\Const_[] $consts Constant declarations
  14307. * @param int $flags Modifiers
  14308. * @param array<string, mixed> $attributes Additional attributes
  14309. * @param list<Node\AttributeGroup> $attrGroups PHP attribute groups
  14310. * @param null|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration
  14311. */
  14312. public function __construct(array $consts, int $flags = 0, array $attributes = [], array $attrGroups = [], ?Node $type = null)
  14313. {
  14314. $this->attributes = $attributes;
  14315. $this->flags = $flags;
  14316. $this->consts = $consts;
  14317. $this->attrGroups = $attrGroups;
  14318. $this->type = $type;
  14319. }
  14320. public function getSubNodeNames(): array
  14321. {
  14322. return ['attrGroups', 'flags', 'type', 'consts'];
  14323. }
  14324. /**
  14325. * Whether constant is explicitly or implicitly public.
  14326. */
  14327. public function isPublic(): bool
  14328. {
  14329. return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
  14330. }
  14331. /**
  14332. * Whether constant is protected.
  14333. */
  14334. public function isProtected(): bool
  14335. {
  14336. return (bool) ($this->flags & Modifiers::PROTECTED);
  14337. }
  14338. /**
  14339. * Whether constant is private.
  14340. */
  14341. public function isPrivate(): bool
  14342. {
  14343. return (bool) ($this->flags & Modifiers::PRIVATE);
  14344. }
  14345. /**
  14346. * Whether constant is final.
  14347. */
  14348. public function isFinal(): bool
  14349. {
  14350. return (bool) ($this->flags & Modifiers::FINAL);
  14351. }
  14352. public function getType(): string
  14353. {
  14354. return 'Stmt_ClassConst';
  14355. }
  14356. }
  14357. <?php
  14358. declare (strict_types=1);
  14359. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14360. use PHPUnitPHAR\PhpParser\Node;
  14361. use PHPUnitPHAR\PhpParser\Node\PropertyItem;
  14362. abstract class ClassLike extends Node\Stmt
  14363. {
  14364. /** @var Node\Identifier|null Name */
  14365. public ?Node\Identifier $name;
  14366. /** @var Node\Stmt[] Statements */
  14367. public array $stmts;
  14368. /** @var Node\AttributeGroup[] PHP attribute groups */
  14369. public array $attrGroups;
  14370. /** @var Node\Name|null Namespaced name (if using NameResolver) */
  14371. public ?Node\Name $namespacedName;
  14372. /**
  14373. * @return TraitUse[]
  14374. */
  14375. public function getTraitUses(): array
  14376. {
  14377. $traitUses = [];
  14378. foreach ($this->stmts as $stmt) {
  14379. if ($stmt instanceof TraitUse) {
  14380. $traitUses[] = $stmt;
  14381. }
  14382. }
  14383. return $traitUses;
  14384. }
  14385. /**
  14386. * @return ClassConst[]
  14387. */
  14388. public function getConstants(): array
  14389. {
  14390. $constants = [];
  14391. foreach ($this->stmts as $stmt) {
  14392. if ($stmt instanceof ClassConst) {
  14393. $constants[] = $stmt;
  14394. }
  14395. }
  14396. return $constants;
  14397. }
  14398. /**
  14399. * @return Property[]
  14400. */
  14401. public function getProperties(): array
  14402. {
  14403. $properties = [];
  14404. foreach ($this->stmts as $stmt) {
  14405. if ($stmt instanceof Property) {
  14406. $properties[] = $stmt;
  14407. }
  14408. }
  14409. return $properties;
  14410. }
  14411. /**
  14412. * Gets property with the given name defined directly in this class/interface/trait.
  14413. *
  14414. * @param string $name Name of the property
  14415. *
  14416. * @return Property|null Property node or null if the property does not exist
  14417. */
  14418. public function getProperty(string $name): ?Property
  14419. {
  14420. foreach ($this->stmts as $stmt) {
  14421. if ($stmt instanceof Property) {
  14422. foreach ($stmt->props as $prop) {
  14423. if ($prop instanceof PropertyItem && $name === $prop->name->toString()) {
  14424. return $stmt;
  14425. }
  14426. }
  14427. }
  14428. }
  14429. return null;
  14430. }
  14431. /**
  14432. * Gets all methods defined directly in this class/interface/trait
  14433. *
  14434. * @return ClassMethod[]
  14435. */
  14436. public function getMethods(): array
  14437. {
  14438. $methods = [];
  14439. foreach ($this->stmts as $stmt) {
  14440. if ($stmt instanceof ClassMethod) {
  14441. $methods[] = $stmt;
  14442. }
  14443. }
  14444. return $methods;
  14445. }
  14446. /**
  14447. * Gets method with the given name defined directly in this class/interface/trait.
  14448. *
  14449. * @param string $name Name of the method (compared case-insensitively)
  14450. *
  14451. * @return ClassMethod|null Method node or null if the method does not exist
  14452. */
  14453. public function getMethod(string $name): ?ClassMethod
  14454. {
  14455. $lowerName = strtolower($name);
  14456. foreach ($this->stmts as $stmt) {
  14457. if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) {
  14458. return $stmt;
  14459. }
  14460. }
  14461. return null;
  14462. }
  14463. }
  14464. <?php
  14465. declare (strict_types=1);
  14466. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14467. use PHPUnitPHAR\PhpParser\Modifiers;
  14468. use PHPUnitPHAR\PhpParser\Node;
  14469. use PHPUnitPHAR\PhpParser\Node\FunctionLike;
  14470. class ClassMethod extends Node\Stmt implements FunctionLike
  14471. {
  14472. /** @var int Flags */
  14473. public int $flags;
  14474. /** @var bool Whether to return by reference */
  14475. public bool $byRef;
  14476. /** @var Node\Identifier Name */
  14477. public Node\Identifier $name;
  14478. /** @var Node\Param[] Parameters */
  14479. public array $params;
  14480. /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
  14481. public ?Node $returnType;
  14482. /** @var Node\Stmt[]|null Statements */
  14483. public ?array $stmts;
  14484. /** @var Node\AttributeGroup[] PHP attribute groups */
  14485. public array $attrGroups;
  14486. /** @var array<string, bool> */
  14487. private static array $magicNames = ['__construct' => \true, '__destruct' => \true, '__call' => \true, '__callstatic' => \true, '__get' => \true, '__set' => \true, '__isset' => \true, '__unset' => \true, '__sleep' => \true, '__wakeup' => \true, '__tostring' => \true, '__set_state' => \true, '__clone' => \true, '__invoke' => \true, '__debuginfo' => \true, '__serialize' => \true, '__unserialize' => \true];
  14488. /**
  14489. * Constructs a class method node.
  14490. *
  14491. * @param string|Node\Identifier $name Name
  14492. * @param array{
  14493. * flags?: int,
  14494. * byRef?: bool,
  14495. * params?: Node\Param[],
  14496. * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
  14497. * stmts?: Node\Stmt[]|null,
  14498. * attrGroups?: Node\AttributeGroup[],
  14499. * } $subNodes Array of the following optional subnodes:
  14500. * 'flags => 0 : Flags
  14501. * 'byRef' => false : Whether to return by reference
  14502. * 'params' => array() : Parameters
  14503. * 'returnType' => null : Return type
  14504. * 'stmts' => array() : Statements
  14505. * 'attrGroups' => array() : PHP attribute groups
  14506. * @param array<string, mixed> $attributes Additional attributes
  14507. */
  14508. public function __construct($name, array $subNodes = [], array $attributes = [])
  14509. {
  14510. $this->attributes = $attributes;
  14511. $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
  14512. $this->byRef = $subNodes['byRef'] ?? \false;
  14513. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  14514. $this->params = $subNodes['params'] ?? [];
  14515. $this->returnType = $subNodes['returnType'] ?? null;
  14516. $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
  14517. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  14518. }
  14519. public function getSubNodeNames(): array
  14520. {
  14521. return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
  14522. }
  14523. public function returnsByRef(): bool
  14524. {
  14525. return $this->byRef;
  14526. }
  14527. public function getParams(): array
  14528. {
  14529. return $this->params;
  14530. }
  14531. public function getReturnType()
  14532. {
  14533. return $this->returnType;
  14534. }
  14535. public function getStmts(): ?array
  14536. {
  14537. return $this->stmts;
  14538. }
  14539. public function getAttrGroups(): array
  14540. {
  14541. return $this->attrGroups;
  14542. }
  14543. /**
  14544. * Whether the method is explicitly or implicitly public.
  14545. */
  14546. public function isPublic(): bool
  14547. {
  14548. return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
  14549. }
  14550. /**
  14551. * Whether the method is protected.
  14552. */
  14553. public function isProtected(): bool
  14554. {
  14555. return (bool) ($this->flags & Modifiers::PROTECTED);
  14556. }
  14557. /**
  14558. * Whether the method is private.
  14559. */
  14560. public function isPrivate(): bool
  14561. {
  14562. return (bool) ($this->flags & Modifiers::PRIVATE);
  14563. }
  14564. /**
  14565. * Whether the method is abstract.
  14566. */
  14567. public function isAbstract(): bool
  14568. {
  14569. return (bool) ($this->flags & Modifiers::ABSTRACT);
  14570. }
  14571. /**
  14572. * Whether the method is final.
  14573. */
  14574. public function isFinal(): bool
  14575. {
  14576. return (bool) ($this->flags & Modifiers::FINAL);
  14577. }
  14578. /**
  14579. * Whether the method is static.
  14580. */
  14581. public function isStatic(): bool
  14582. {
  14583. return (bool) ($this->flags & Modifiers::STATIC);
  14584. }
  14585. /**
  14586. * Whether the method is magic.
  14587. */
  14588. public function isMagic(): bool
  14589. {
  14590. return isset(self::$magicNames[$this->name->toLowerString()]);
  14591. }
  14592. public function getType(): string
  14593. {
  14594. return 'Stmt_ClassMethod';
  14595. }
  14596. }
  14597. <?php
  14598. declare (strict_types=1);
  14599. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14600. use PHPUnitPHAR\PhpParser\Modifiers;
  14601. use PHPUnitPHAR\PhpParser\Node;
  14602. class Class_ extends ClassLike
  14603. {
  14604. /** @deprecated Use Modifiers::PUBLIC instead */
  14605. public const MODIFIER_PUBLIC = 1;
  14606. /** @deprecated Use Modifiers::PROTECTED instead */
  14607. public const MODIFIER_PROTECTED = 2;
  14608. /** @deprecated Use Modifiers::PRIVATE instead */
  14609. public const MODIFIER_PRIVATE = 4;
  14610. /** @deprecated Use Modifiers::STATIC instead */
  14611. public const MODIFIER_STATIC = 8;
  14612. /** @deprecated Use Modifiers::ABSTRACT instead */
  14613. public const MODIFIER_ABSTRACT = 16;
  14614. /** @deprecated Use Modifiers::FINAL instead */
  14615. public const MODIFIER_FINAL = 32;
  14616. /** @deprecated Use Modifiers::READONLY instead */
  14617. public const MODIFIER_READONLY = 64;
  14618. /** @deprecated Use Modifiers::VISIBILITY_MASK instead */
  14619. public const VISIBILITY_MODIFIER_MASK = 7;
  14620. // 1 | 2 | 4
  14621. /** @var int Modifiers */
  14622. public int $flags;
  14623. /** @var null|Node\Name Name of extended class */
  14624. public ?Node\Name $extends;
  14625. /** @var Node\Name[] Names of implemented interfaces */
  14626. public array $implements;
  14627. /**
  14628. * Constructs a class node.
  14629. *
  14630. * @param string|Node\Identifier|null $name Name
  14631. * @param array{
  14632. * flags?: int,
  14633. * extends?: Node\Name|null,
  14634. * implements?: Node\Name[],
  14635. * stmts?: Node\Stmt[],
  14636. * attrGroups?: Node\AttributeGroup[],
  14637. * } $subNodes Array of the following optional subnodes:
  14638. * 'flags' => 0 : Flags
  14639. * 'extends' => null : Name of extended class
  14640. * 'implements' => array(): Names of implemented interfaces
  14641. * 'stmts' => array(): Statements
  14642. * 'attrGroups' => array(): PHP attribute groups
  14643. * @param array<string, mixed> $attributes Additional attributes
  14644. */
  14645. public function __construct($name, array $subNodes = [], array $attributes = [])
  14646. {
  14647. $this->attributes = $attributes;
  14648. $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
  14649. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  14650. $this->extends = $subNodes['extends'] ?? null;
  14651. $this->implements = $subNodes['implements'] ?? [];
  14652. $this->stmts = $subNodes['stmts'] ?? [];
  14653. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  14654. }
  14655. public function getSubNodeNames(): array
  14656. {
  14657. return ['attrGroups', 'flags', 'name', 'extends', 'implements', 'stmts'];
  14658. }
  14659. /**
  14660. * Whether the class is explicitly abstract.
  14661. */
  14662. public function isAbstract(): bool
  14663. {
  14664. return (bool) ($this->flags & Modifiers::ABSTRACT);
  14665. }
  14666. /**
  14667. * Whether the class is final.
  14668. */
  14669. public function isFinal(): bool
  14670. {
  14671. return (bool) ($this->flags & Modifiers::FINAL);
  14672. }
  14673. public function isReadonly(): bool
  14674. {
  14675. return (bool) ($this->flags & Modifiers::READONLY);
  14676. }
  14677. /**
  14678. * Whether the class is anonymous.
  14679. */
  14680. public function isAnonymous(): bool
  14681. {
  14682. return null === $this->name;
  14683. }
  14684. public function getType(): string
  14685. {
  14686. return 'Stmt_Class';
  14687. }
  14688. }
  14689. <?php
  14690. declare (strict_types=1);
  14691. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14692. use PHPUnitPHAR\PhpParser\Node;
  14693. class Const_ extends Node\Stmt
  14694. {
  14695. /** @var Node\Const_[] Constant declarations */
  14696. public array $consts;
  14697. /**
  14698. * Constructs a const list node.
  14699. *
  14700. * @param Node\Const_[] $consts Constant declarations
  14701. * @param array<string, mixed> $attributes Additional attributes
  14702. */
  14703. public function __construct(array $consts, array $attributes = [])
  14704. {
  14705. $this->attributes = $attributes;
  14706. $this->consts = $consts;
  14707. }
  14708. public function getSubNodeNames(): array
  14709. {
  14710. return ['consts'];
  14711. }
  14712. public function getType(): string
  14713. {
  14714. return 'Stmt_Const';
  14715. }
  14716. }
  14717. <?php
  14718. declare (strict_types=1);
  14719. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14720. use PHPUnitPHAR\PhpParser\Node;
  14721. class Continue_ extends Node\Stmt
  14722. {
  14723. /** @var null|Node\Expr Number of loops to continue */
  14724. public ?Node\Expr $num;
  14725. /**
  14726. * Constructs a continue node.
  14727. *
  14728. * @param null|Node\Expr $num Number of loops to continue
  14729. * @param array<string, mixed> $attributes Additional attributes
  14730. */
  14731. public function __construct(?Node\Expr $num = null, array $attributes = [])
  14732. {
  14733. $this->attributes = $attributes;
  14734. $this->num = $num;
  14735. }
  14736. public function getSubNodeNames(): array
  14737. {
  14738. return ['num'];
  14739. }
  14740. public function getType(): string
  14741. {
  14742. return 'Stmt_Continue';
  14743. }
  14744. }
  14745. <?php
  14746. declare (strict_types=1);
  14747. namespace PHPUnitPHAR;
  14748. require __DIR__ . '/../DeclareItem.php';
  14749. <?php
  14750. declare (strict_types=1);
  14751. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14752. use PHPUnitPHAR\PhpParser\Node;
  14753. use PHPUnitPHAR\PhpParser\Node\DeclareItem;
  14754. class Declare_ extends Node\Stmt
  14755. {
  14756. /** @var DeclareItem[] List of declares */
  14757. public array $declares;
  14758. /** @var Node\Stmt[]|null Statements */
  14759. public ?array $stmts;
  14760. /**
  14761. * Constructs a declare node.
  14762. *
  14763. * @param DeclareItem[] $declares List of declares
  14764. * @param Node\Stmt[]|null $stmts Statements
  14765. * @param array<string, mixed> $attributes Additional attributes
  14766. */
  14767. public function __construct(array $declares, ?array $stmts = null, array $attributes = [])
  14768. {
  14769. $this->attributes = $attributes;
  14770. $this->declares = $declares;
  14771. $this->stmts = $stmts;
  14772. }
  14773. public function getSubNodeNames(): array
  14774. {
  14775. return ['declares', 'stmts'];
  14776. }
  14777. public function getType(): string
  14778. {
  14779. return 'Stmt_Declare';
  14780. }
  14781. }
  14782. <?php
  14783. declare (strict_types=1);
  14784. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14785. use PHPUnitPHAR\PhpParser\Node;
  14786. class Do_ extends Node\Stmt
  14787. {
  14788. /** @var Node\Stmt[] Statements */
  14789. public array $stmts;
  14790. /** @var Node\Expr Condition */
  14791. public Node\Expr $cond;
  14792. /**
  14793. * Constructs a do while node.
  14794. *
  14795. * @param Node\Expr $cond Condition
  14796. * @param Node\Stmt[] $stmts Statements
  14797. * @param array<string, mixed> $attributes Additional attributes
  14798. */
  14799. public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
  14800. {
  14801. $this->attributes = $attributes;
  14802. $this->cond = $cond;
  14803. $this->stmts = $stmts;
  14804. }
  14805. public function getSubNodeNames(): array
  14806. {
  14807. return ['stmts', 'cond'];
  14808. }
  14809. public function getType(): string
  14810. {
  14811. return 'Stmt_Do';
  14812. }
  14813. }
  14814. <?php
  14815. declare (strict_types=1);
  14816. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14817. use PHPUnitPHAR\PhpParser\Node;
  14818. class Echo_ extends Node\Stmt
  14819. {
  14820. /** @var Node\Expr[] Expressions */
  14821. public array $exprs;
  14822. /**
  14823. * Constructs an echo node.
  14824. *
  14825. * @param Node\Expr[] $exprs Expressions
  14826. * @param array<string, mixed> $attributes Additional attributes
  14827. */
  14828. public function __construct(array $exprs, array $attributes = [])
  14829. {
  14830. $this->attributes = $attributes;
  14831. $this->exprs = $exprs;
  14832. }
  14833. public function getSubNodeNames(): array
  14834. {
  14835. return ['exprs'];
  14836. }
  14837. public function getType(): string
  14838. {
  14839. return 'Stmt_Echo';
  14840. }
  14841. }
  14842. <?php
  14843. declare (strict_types=1);
  14844. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14845. use PHPUnitPHAR\PhpParser\Node;
  14846. class ElseIf_ extends Node\Stmt
  14847. {
  14848. /** @var Node\Expr Condition */
  14849. public Node\Expr $cond;
  14850. /** @var Node\Stmt[] Statements */
  14851. public array $stmts;
  14852. /**
  14853. * Constructs an elseif node.
  14854. *
  14855. * @param Node\Expr $cond Condition
  14856. * @param Node\Stmt[] $stmts Statements
  14857. * @param array<string, mixed> $attributes Additional attributes
  14858. */
  14859. public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
  14860. {
  14861. $this->attributes = $attributes;
  14862. $this->cond = $cond;
  14863. $this->stmts = $stmts;
  14864. }
  14865. public function getSubNodeNames(): array
  14866. {
  14867. return ['cond', 'stmts'];
  14868. }
  14869. public function getType(): string
  14870. {
  14871. return 'Stmt_ElseIf';
  14872. }
  14873. }
  14874. <?php
  14875. declare (strict_types=1);
  14876. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14877. use PHPUnitPHAR\PhpParser\Node;
  14878. class Else_ extends Node\Stmt
  14879. {
  14880. /** @var Node\Stmt[] Statements */
  14881. public array $stmts;
  14882. /**
  14883. * Constructs an else node.
  14884. *
  14885. * @param Node\Stmt[] $stmts Statements
  14886. * @param array<string, mixed> $attributes Additional attributes
  14887. */
  14888. public function __construct(array $stmts = [], array $attributes = [])
  14889. {
  14890. $this->attributes = $attributes;
  14891. $this->stmts = $stmts;
  14892. }
  14893. public function getSubNodeNames(): array
  14894. {
  14895. return ['stmts'];
  14896. }
  14897. public function getType(): string
  14898. {
  14899. return 'Stmt_Else';
  14900. }
  14901. }
  14902. <?php
  14903. declare (strict_types=1);
  14904. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14905. use PHPUnitPHAR\PhpParser\Node;
  14906. use PHPUnitPHAR\PhpParser\Node\AttributeGroup;
  14907. class EnumCase extends Node\Stmt
  14908. {
  14909. /** @var Node\Identifier Enum case name */
  14910. public Node\Identifier $name;
  14911. /** @var Node\Expr|null Enum case expression */
  14912. public ?Node\Expr $expr;
  14913. /** @var Node\AttributeGroup[] PHP attribute groups */
  14914. public array $attrGroups;
  14915. /**
  14916. * @param string|Node\Identifier $name Enum case name
  14917. * @param Node\Expr|null $expr Enum case expression
  14918. * @param list<AttributeGroup> $attrGroups PHP attribute groups
  14919. * @param array<string, mixed> $attributes Additional attributes
  14920. */
  14921. public function __construct($name, ?Node\Expr $expr = null, array $attrGroups = [], array $attributes = [])
  14922. {
  14923. parent::__construct($attributes);
  14924. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  14925. $this->expr = $expr;
  14926. $this->attrGroups = $attrGroups;
  14927. }
  14928. public function getSubNodeNames(): array
  14929. {
  14930. return ['attrGroups', 'name', 'expr'];
  14931. }
  14932. public function getType(): string
  14933. {
  14934. return 'Stmt_EnumCase';
  14935. }
  14936. }
  14937. <?php
  14938. declare (strict_types=1);
  14939. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14940. use PHPUnitPHAR\PhpParser\Node;
  14941. class Enum_ extends ClassLike
  14942. {
  14943. /** @var null|Node\Identifier Scalar Type */
  14944. public ?Node $scalarType;
  14945. /** @var Node\Name[] Names of implemented interfaces */
  14946. public array $implements;
  14947. /**
  14948. * @param string|Node\Identifier|null $name Name
  14949. * @param array{
  14950. * scalarType?: Node\Identifier|null,
  14951. * implements?: Node\Name[],
  14952. * stmts?: Node\Stmt[],
  14953. * attrGroups?: Node\AttributeGroup[],
  14954. * } $subNodes Array of the following optional subnodes:
  14955. * 'scalarType' => null : Scalar type
  14956. * 'implements' => array() : Names of implemented interfaces
  14957. * 'stmts' => array() : Statements
  14958. * 'attrGroups' => array() : PHP attribute groups
  14959. * @param array<string, mixed> $attributes Additional attributes
  14960. */
  14961. public function __construct($name, array $subNodes = [], array $attributes = [])
  14962. {
  14963. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  14964. $this->scalarType = $subNodes['scalarType'] ?? null;
  14965. $this->implements = $subNodes['implements'] ?? [];
  14966. $this->stmts = $subNodes['stmts'] ?? [];
  14967. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  14968. parent::__construct($attributes);
  14969. }
  14970. public function getSubNodeNames(): array
  14971. {
  14972. return ['attrGroups', 'name', 'scalarType', 'implements', 'stmts'];
  14973. }
  14974. public function getType(): string
  14975. {
  14976. return 'Stmt_Enum';
  14977. }
  14978. }
  14979. <?php
  14980. declare (strict_types=1);
  14981. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  14982. use PHPUnitPHAR\PhpParser\Node;
  14983. /**
  14984. * Represents statements of type "expr;"
  14985. */
  14986. class Expression extends Node\Stmt
  14987. {
  14988. /** @var Node\Expr Expression */
  14989. public Node\Expr $expr;
  14990. /**
  14991. * Constructs an expression statement.
  14992. *
  14993. * @param Node\Expr $expr Expression
  14994. * @param array<string, mixed> $attributes Additional attributes
  14995. */
  14996. public function __construct(Node\Expr $expr, array $attributes = [])
  14997. {
  14998. $this->attributes = $attributes;
  14999. $this->expr = $expr;
  15000. }
  15001. public function getSubNodeNames(): array
  15002. {
  15003. return ['expr'];
  15004. }
  15005. public function getType(): string
  15006. {
  15007. return 'Stmt_Expression';
  15008. }
  15009. }
  15010. <?php
  15011. declare (strict_types=1);
  15012. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15013. use PHPUnitPHAR\PhpParser\Node;
  15014. class Finally_ extends Node\Stmt
  15015. {
  15016. /** @var Node\Stmt[] Statements */
  15017. public array $stmts;
  15018. /**
  15019. * Constructs a finally node.
  15020. *
  15021. * @param Node\Stmt[] $stmts Statements
  15022. * @param array<string, mixed> $attributes Additional attributes
  15023. */
  15024. public function __construct(array $stmts = [], array $attributes = [])
  15025. {
  15026. $this->attributes = $attributes;
  15027. $this->stmts = $stmts;
  15028. }
  15029. public function getSubNodeNames(): array
  15030. {
  15031. return ['stmts'];
  15032. }
  15033. public function getType(): string
  15034. {
  15035. return 'Stmt_Finally';
  15036. }
  15037. }
  15038. <?php
  15039. declare (strict_types=1);
  15040. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15041. use PHPUnitPHAR\PhpParser\Node;
  15042. class For_ extends Node\Stmt
  15043. {
  15044. /** @var Node\Expr[] Init expressions */
  15045. public array $init;
  15046. /** @var Node\Expr[] Loop conditions */
  15047. public array $cond;
  15048. /** @var Node\Expr[] Loop expressions */
  15049. public array $loop;
  15050. /** @var Node\Stmt[] Statements */
  15051. public array $stmts;
  15052. /**
  15053. * Constructs a for loop node.
  15054. *
  15055. * @param array{
  15056. * init?: Node\Expr[],
  15057. * cond?: Node\Expr[],
  15058. * loop?: Node\Expr[],
  15059. * stmts?: Node\Stmt[],
  15060. * } $subNodes Array of the following optional subnodes:
  15061. * 'init' => array(): Init expressions
  15062. * 'cond' => array(): Loop conditions
  15063. * 'loop' => array(): Loop expressions
  15064. * 'stmts' => array(): Statements
  15065. * @param array<string, mixed> $attributes Additional attributes
  15066. */
  15067. public function __construct(array $subNodes = [], array $attributes = [])
  15068. {
  15069. $this->attributes = $attributes;
  15070. $this->init = $subNodes['init'] ?? [];
  15071. $this->cond = $subNodes['cond'] ?? [];
  15072. $this->loop = $subNodes['loop'] ?? [];
  15073. $this->stmts = $subNodes['stmts'] ?? [];
  15074. }
  15075. public function getSubNodeNames(): array
  15076. {
  15077. return ['init', 'cond', 'loop', 'stmts'];
  15078. }
  15079. public function getType(): string
  15080. {
  15081. return 'Stmt_For';
  15082. }
  15083. }
  15084. <?php
  15085. declare (strict_types=1);
  15086. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15087. use PHPUnitPHAR\PhpParser\Node;
  15088. class Foreach_ extends Node\Stmt
  15089. {
  15090. /** @var Node\Expr Expression to iterate */
  15091. public Node\Expr $expr;
  15092. /** @var null|Node\Expr Variable to assign key to */
  15093. public ?Node\Expr $keyVar;
  15094. /** @var bool Whether to assign value by reference */
  15095. public bool $byRef;
  15096. /** @var Node\Expr Variable to assign value to */
  15097. public Node\Expr $valueVar;
  15098. /** @var Node\Stmt[] Statements */
  15099. public array $stmts;
  15100. /**
  15101. * Constructs a foreach node.
  15102. *
  15103. * @param Node\Expr $expr Expression to iterate
  15104. * @param Node\Expr $valueVar Variable to assign value to
  15105. * @param array{
  15106. * keyVar?: Node\Expr|null,
  15107. * byRef?: bool,
  15108. * stmts?: Node\Stmt[],
  15109. * } $subNodes Array of the following optional subnodes:
  15110. * 'keyVar' => null : Variable to assign key to
  15111. * 'byRef' => false : Whether to assign value by reference
  15112. * 'stmts' => array(): Statements
  15113. * @param array<string, mixed> $attributes Additional attributes
  15114. */
  15115. public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = [])
  15116. {
  15117. $this->attributes = $attributes;
  15118. $this->expr = $expr;
  15119. $this->keyVar = $subNodes['keyVar'] ?? null;
  15120. $this->byRef = $subNodes['byRef'] ?? \false;
  15121. $this->valueVar = $valueVar;
  15122. $this->stmts = $subNodes['stmts'] ?? [];
  15123. }
  15124. public function getSubNodeNames(): array
  15125. {
  15126. return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts'];
  15127. }
  15128. public function getType(): string
  15129. {
  15130. return 'Stmt_Foreach';
  15131. }
  15132. }
  15133. <?php
  15134. declare (strict_types=1);
  15135. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15136. use PHPUnitPHAR\PhpParser\Node;
  15137. use PHPUnitPHAR\PhpParser\Node\FunctionLike;
  15138. class Function_ extends Node\Stmt implements FunctionLike
  15139. {
  15140. /** @var bool Whether function returns by reference */
  15141. public bool $byRef;
  15142. /** @var Node\Identifier Name */
  15143. public Node\Identifier $name;
  15144. /** @var Node\Param[] Parameters */
  15145. public array $params;
  15146. /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
  15147. public ?Node $returnType;
  15148. /** @var Node\Stmt[] Statements */
  15149. public array $stmts;
  15150. /** @var Node\AttributeGroup[] PHP attribute groups */
  15151. public array $attrGroups;
  15152. /** @var Node\Name|null Namespaced name (if using NameResolver) */
  15153. public ?Node\Name $namespacedName;
  15154. /**
  15155. * Constructs a function node.
  15156. *
  15157. * @param string|Node\Identifier $name Name
  15158. * @param array{
  15159. * byRef?: bool,
  15160. * params?: Node\Param[],
  15161. * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
  15162. * stmts?: Node\Stmt[],
  15163. * attrGroups?: Node\AttributeGroup[],
  15164. * } $subNodes Array of the following optional subnodes:
  15165. * 'byRef' => false : Whether to return by reference
  15166. * 'params' => array(): Parameters
  15167. * 'returnType' => null : Return type
  15168. * 'stmts' => array(): Statements
  15169. * 'attrGroups' => array(): PHP attribute groups
  15170. * @param array<string, mixed> $attributes Additional attributes
  15171. */
  15172. public function __construct($name, array $subNodes = [], array $attributes = [])
  15173. {
  15174. $this->attributes = $attributes;
  15175. $this->byRef = $subNodes['byRef'] ?? \false;
  15176. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  15177. $this->params = $subNodes['params'] ?? [];
  15178. $this->returnType = $subNodes['returnType'] ?? null;
  15179. $this->stmts = $subNodes['stmts'] ?? [];
  15180. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  15181. }
  15182. public function getSubNodeNames(): array
  15183. {
  15184. return ['attrGroups', 'byRef', 'name', 'params', 'returnType', 'stmts'];
  15185. }
  15186. public function returnsByRef(): bool
  15187. {
  15188. return $this->byRef;
  15189. }
  15190. public function getParams(): array
  15191. {
  15192. return $this->params;
  15193. }
  15194. public function getReturnType()
  15195. {
  15196. return $this->returnType;
  15197. }
  15198. public function getAttrGroups(): array
  15199. {
  15200. return $this->attrGroups;
  15201. }
  15202. /** @return Node\Stmt[] */
  15203. public function getStmts(): array
  15204. {
  15205. return $this->stmts;
  15206. }
  15207. public function getType(): string
  15208. {
  15209. return 'Stmt_Function';
  15210. }
  15211. }
  15212. <?php
  15213. declare (strict_types=1);
  15214. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15215. use PHPUnitPHAR\PhpParser\Node;
  15216. class Global_ extends Node\Stmt
  15217. {
  15218. /** @var Node\Expr[] Variables */
  15219. public array $vars;
  15220. /**
  15221. * Constructs a global variables list node.
  15222. *
  15223. * @param Node\Expr[] $vars Variables to unset
  15224. * @param array<string, mixed> $attributes Additional attributes
  15225. */
  15226. public function __construct(array $vars, array $attributes = [])
  15227. {
  15228. $this->attributes = $attributes;
  15229. $this->vars = $vars;
  15230. }
  15231. public function getSubNodeNames(): array
  15232. {
  15233. return ['vars'];
  15234. }
  15235. public function getType(): string
  15236. {
  15237. return 'Stmt_Global';
  15238. }
  15239. }
  15240. <?php
  15241. declare (strict_types=1);
  15242. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15243. use PHPUnitPHAR\PhpParser\Node\Identifier;
  15244. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15245. class Goto_ extends Stmt
  15246. {
  15247. /** @var Identifier Name of label to jump to */
  15248. public Identifier $name;
  15249. /**
  15250. * Constructs a goto node.
  15251. *
  15252. * @param string|Identifier $name Name of label to jump to
  15253. * @param array<string, mixed> $attributes Additional attributes
  15254. */
  15255. public function __construct($name, array $attributes = [])
  15256. {
  15257. $this->attributes = $attributes;
  15258. $this->name = \is_string($name) ? new Identifier($name) : $name;
  15259. }
  15260. public function getSubNodeNames(): array
  15261. {
  15262. return ['name'];
  15263. }
  15264. public function getType(): string
  15265. {
  15266. return 'Stmt_Goto';
  15267. }
  15268. }
  15269. <?php
  15270. declare (strict_types=1);
  15271. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15272. use PHPUnitPHAR\PhpParser\Node\Name;
  15273. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15274. use PHPUnitPHAR\PhpParser\Node\UseItem;
  15275. class GroupUse extends Stmt
  15276. {
  15277. /**
  15278. * @var Use_::TYPE_* Type of group use
  15279. */
  15280. public int $type;
  15281. /** @var Name Prefix for uses */
  15282. public Name $prefix;
  15283. /** @var UseItem[] Uses */
  15284. public array $uses;
  15285. /**
  15286. * Constructs a group use node.
  15287. *
  15288. * @param Name $prefix Prefix for uses
  15289. * @param UseItem[] $uses Uses
  15290. * @param Use_::TYPE_* $type Type of group use
  15291. * @param array<string, mixed> $attributes Additional attributes
  15292. */
  15293. public function __construct(Name $prefix, array $uses, int $type = Use_::TYPE_NORMAL, array $attributes = [])
  15294. {
  15295. $this->attributes = $attributes;
  15296. $this->type = $type;
  15297. $this->prefix = $prefix;
  15298. $this->uses = $uses;
  15299. }
  15300. public function getSubNodeNames(): array
  15301. {
  15302. return ['type', 'prefix', 'uses'];
  15303. }
  15304. public function getType(): string
  15305. {
  15306. return 'Stmt_GroupUse';
  15307. }
  15308. }
  15309. <?php
  15310. declare (strict_types=1);
  15311. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15312. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15313. class HaltCompiler extends Stmt
  15314. {
  15315. /** @var string Remaining text after halt compiler statement. */
  15316. public string $remaining;
  15317. /**
  15318. * Constructs a __halt_compiler node.
  15319. *
  15320. * @param string $remaining Remaining text after halt compiler statement.
  15321. * @param array<string, mixed> $attributes Additional attributes
  15322. */
  15323. public function __construct(string $remaining, array $attributes = [])
  15324. {
  15325. $this->attributes = $attributes;
  15326. $this->remaining = $remaining;
  15327. }
  15328. public function getSubNodeNames(): array
  15329. {
  15330. return ['remaining'];
  15331. }
  15332. public function getType(): string
  15333. {
  15334. return 'Stmt_HaltCompiler';
  15335. }
  15336. }
  15337. <?php
  15338. declare (strict_types=1);
  15339. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15340. use PHPUnitPHAR\PhpParser\Node;
  15341. class If_ extends Node\Stmt
  15342. {
  15343. /** @var Node\Expr Condition expression */
  15344. public Node\Expr $cond;
  15345. /** @var Node\Stmt[] Statements */
  15346. public array $stmts;
  15347. /** @var ElseIf_[] Elseif clauses */
  15348. public array $elseifs;
  15349. /** @var null|Else_ Else clause */
  15350. public ?Else_ $else;
  15351. /**
  15352. * Constructs an if node.
  15353. *
  15354. * @param Node\Expr $cond Condition
  15355. * @param array{
  15356. * stmts?: Node\Stmt[],
  15357. * elseifs?: ElseIf_[],
  15358. * else?: Else_|null,
  15359. * } $subNodes Array of the following optional subnodes:
  15360. * 'stmts' => array(): Statements
  15361. * 'elseifs' => array(): Elseif clauses
  15362. * 'else' => null : Else clause
  15363. * @param array<string, mixed> $attributes Additional attributes
  15364. */
  15365. public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = [])
  15366. {
  15367. $this->attributes = $attributes;
  15368. $this->cond = $cond;
  15369. $this->stmts = $subNodes['stmts'] ?? [];
  15370. $this->elseifs = $subNodes['elseifs'] ?? [];
  15371. $this->else = $subNodes['else'] ?? null;
  15372. }
  15373. public function getSubNodeNames(): array
  15374. {
  15375. return ['cond', 'stmts', 'elseifs', 'else'];
  15376. }
  15377. public function getType(): string
  15378. {
  15379. return 'Stmt_If';
  15380. }
  15381. }
  15382. <?php
  15383. declare (strict_types=1);
  15384. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15385. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15386. class InlineHTML extends Stmt
  15387. {
  15388. /** @var string String */
  15389. public string $value;
  15390. /**
  15391. * Constructs an inline HTML node.
  15392. *
  15393. * @param string $value String
  15394. * @param array<string, mixed> $attributes Additional attributes
  15395. */
  15396. public function __construct(string $value, array $attributes = [])
  15397. {
  15398. $this->attributes = $attributes;
  15399. $this->value = $value;
  15400. }
  15401. public function getSubNodeNames(): array
  15402. {
  15403. return ['value'];
  15404. }
  15405. public function getType(): string
  15406. {
  15407. return 'Stmt_InlineHTML';
  15408. }
  15409. }
  15410. <?php
  15411. declare (strict_types=1);
  15412. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15413. use PHPUnitPHAR\PhpParser\Node;
  15414. class Interface_ extends ClassLike
  15415. {
  15416. /** @var Node\Name[] Extended interfaces */
  15417. public array $extends;
  15418. /**
  15419. * Constructs a class node.
  15420. *
  15421. * @param string|Node\Identifier $name Name
  15422. * @param array{
  15423. * extends?: Node\Name[],
  15424. * stmts?: Node\Stmt[],
  15425. * attrGroups?: Node\AttributeGroup[],
  15426. * } $subNodes Array of the following optional subnodes:
  15427. * 'extends' => array(): Name of extended interfaces
  15428. * 'stmts' => array(): Statements
  15429. * 'attrGroups' => array(): PHP attribute groups
  15430. * @param array<string, mixed> $attributes Additional attributes
  15431. */
  15432. public function __construct($name, array $subNodes = [], array $attributes = [])
  15433. {
  15434. $this->attributes = $attributes;
  15435. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  15436. $this->extends = $subNodes['extends'] ?? [];
  15437. $this->stmts = $subNodes['stmts'] ?? [];
  15438. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  15439. }
  15440. public function getSubNodeNames(): array
  15441. {
  15442. return ['attrGroups', 'name', 'extends', 'stmts'];
  15443. }
  15444. public function getType(): string
  15445. {
  15446. return 'Stmt_Interface';
  15447. }
  15448. }
  15449. <?php
  15450. declare (strict_types=1);
  15451. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15452. use PHPUnitPHAR\PhpParser\Node\Identifier;
  15453. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15454. class Label extends Stmt
  15455. {
  15456. /** @var Identifier Name */
  15457. public Identifier $name;
  15458. /**
  15459. * Constructs a label node.
  15460. *
  15461. * @param string|Identifier $name Name
  15462. * @param array<string, mixed> $attributes Additional attributes
  15463. */
  15464. public function __construct($name, array $attributes = [])
  15465. {
  15466. $this->attributes = $attributes;
  15467. $this->name = \is_string($name) ? new Identifier($name) : $name;
  15468. }
  15469. public function getSubNodeNames(): array
  15470. {
  15471. return ['name'];
  15472. }
  15473. public function getType(): string
  15474. {
  15475. return 'Stmt_Label';
  15476. }
  15477. }
  15478. <?php
  15479. declare (strict_types=1);
  15480. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15481. use PHPUnitPHAR\PhpParser\Node;
  15482. class Namespace_ extends Node\Stmt
  15483. {
  15484. /* For use in the "kind" attribute */
  15485. public const KIND_SEMICOLON = 1;
  15486. public const KIND_BRACED = 2;
  15487. /** @var null|Node\Name Name */
  15488. public ?Node\Name $name;
  15489. /** @var Node\Stmt[] Statements */
  15490. public $stmts;
  15491. /**
  15492. * Constructs a namespace node.
  15493. *
  15494. * @param null|Node\Name $name Name
  15495. * @param null|Node\Stmt[] $stmts Statements
  15496. * @param array<string, mixed> $attributes Additional attributes
  15497. */
  15498. public function __construct(?Node\Name $name = null, ?array $stmts = [], array $attributes = [])
  15499. {
  15500. $this->attributes = $attributes;
  15501. $this->name = $name;
  15502. $this->stmts = $stmts;
  15503. }
  15504. public function getSubNodeNames(): array
  15505. {
  15506. return ['name', 'stmts'];
  15507. }
  15508. public function getType(): string
  15509. {
  15510. return 'Stmt_Namespace';
  15511. }
  15512. }
  15513. <?php
  15514. declare (strict_types=1);
  15515. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15516. use PHPUnitPHAR\PhpParser\Node;
  15517. /** Nop/empty statement (;). */
  15518. class Nop extends Node\Stmt
  15519. {
  15520. public function getSubNodeNames(): array
  15521. {
  15522. return [];
  15523. }
  15524. public function getType(): string
  15525. {
  15526. return 'Stmt_Nop';
  15527. }
  15528. }
  15529. <?php
  15530. declare (strict_types=1);
  15531. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15532. use PHPUnitPHAR\PhpParser\Modifiers;
  15533. use PHPUnitPHAR\PhpParser\Node;
  15534. use PHPUnitPHAR\PhpParser\Node\ComplexType;
  15535. use PHPUnitPHAR\PhpParser\Node\Identifier;
  15536. use PHPUnitPHAR\PhpParser\Node\Name;
  15537. use PHPUnitPHAR\PhpParser\Node\PropertyItem;
  15538. class Property extends Node\Stmt
  15539. {
  15540. /** @var int Modifiers */
  15541. public int $flags;
  15542. /** @var PropertyItem[] Properties */
  15543. public array $props;
  15544. /** @var null|Identifier|Name|ComplexType Type declaration */
  15545. public ?Node $type;
  15546. /** @var Node\AttributeGroup[] PHP attribute groups */
  15547. public array $attrGroups;
  15548. /** @var Node\PropertyHook[] Property hooks */
  15549. public array $hooks;
  15550. /**
  15551. * Constructs a class property list node.
  15552. *
  15553. * @param int $flags Modifiers
  15554. * @param PropertyItem[] $props Properties
  15555. * @param array<string, mixed> $attributes Additional attributes
  15556. * @param null|Identifier|Name|ComplexType $type Type declaration
  15557. * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
  15558. * @param Node\PropertyHook[] $hooks Property hooks
  15559. */
  15560. public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = [], array $hooks = [])
  15561. {
  15562. $this->attributes = $attributes;
  15563. $this->flags = $flags;
  15564. $this->props = $props;
  15565. $this->type = $type;
  15566. $this->attrGroups = $attrGroups;
  15567. $this->hooks = $hooks;
  15568. }
  15569. public function getSubNodeNames(): array
  15570. {
  15571. return ['attrGroups', 'flags', 'type', 'props', 'hooks'];
  15572. }
  15573. /**
  15574. * Whether the property is explicitly or implicitly public.
  15575. */
  15576. public function isPublic(): bool
  15577. {
  15578. return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
  15579. }
  15580. /**
  15581. * Whether the property is protected.
  15582. */
  15583. public function isProtected(): bool
  15584. {
  15585. return (bool) ($this->flags & Modifiers::PROTECTED);
  15586. }
  15587. /**
  15588. * Whether the property is private.
  15589. */
  15590. public function isPrivate(): bool
  15591. {
  15592. return (bool) ($this->flags & Modifiers::PRIVATE);
  15593. }
  15594. /**
  15595. * Whether the property is static.
  15596. */
  15597. public function isStatic(): bool
  15598. {
  15599. return (bool) ($this->flags & Modifiers::STATIC);
  15600. }
  15601. /**
  15602. * Whether the property is readonly.
  15603. */
  15604. public function isReadonly(): bool
  15605. {
  15606. return (bool) ($this->flags & Modifiers::READONLY);
  15607. }
  15608. /**
  15609. * Whether the property has explicit public(set) visibility.
  15610. */
  15611. public function isPublicSet(): bool
  15612. {
  15613. return (bool) ($this->flags & Modifiers::PUBLIC_SET);
  15614. }
  15615. /**
  15616. * Whether the property has explicit protected(set) visibility.
  15617. */
  15618. public function isProtectedSet(): bool
  15619. {
  15620. return (bool) ($this->flags & Modifiers::PROTECTED_SET);
  15621. }
  15622. /**
  15623. * Whether the property has explicit private(set) visibility.
  15624. */
  15625. public function isPrivateSet(): bool
  15626. {
  15627. return (bool) ($this->flags & Modifiers::PRIVATE_SET);
  15628. }
  15629. public function getType(): string
  15630. {
  15631. return 'Stmt_Property';
  15632. }
  15633. }
  15634. <?php
  15635. declare (strict_types=1);
  15636. namespace PHPUnitPHAR;
  15637. require __DIR__ . '/../PropertyItem.php';
  15638. <?php
  15639. declare (strict_types=1);
  15640. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15641. use PHPUnitPHAR\PhpParser\Node;
  15642. class Return_ extends Node\Stmt
  15643. {
  15644. /** @var null|Node\Expr Expression */
  15645. public ?Node\Expr $expr;
  15646. /**
  15647. * Constructs a return node.
  15648. *
  15649. * @param null|Node\Expr $expr Expression
  15650. * @param array<string, mixed> $attributes Additional attributes
  15651. */
  15652. public function __construct(?Node\Expr $expr = null, array $attributes = [])
  15653. {
  15654. $this->attributes = $attributes;
  15655. $this->expr = $expr;
  15656. }
  15657. public function getSubNodeNames(): array
  15658. {
  15659. return ['expr'];
  15660. }
  15661. public function getType(): string
  15662. {
  15663. return 'Stmt_Return';
  15664. }
  15665. }
  15666. <?php
  15667. declare (strict_types=1);
  15668. namespace PHPUnitPHAR;
  15669. require __DIR__ . '/../StaticVar.php';
  15670. <?php
  15671. declare (strict_types=1);
  15672. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15673. use PHPUnitPHAR\PhpParser\Node\StaticVar;
  15674. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15675. class Static_ extends Stmt
  15676. {
  15677. /** @var StaticVar[] Variable definitions */
  15678. public array $vars;
  15679. /**
  15680. * Constructs a static variables list node.
  15681. *
  15682. * @param StaticVar[] $vars Variable definitions
  15683. * @param array<string, mixed> $attributes Additional attributes
  15684. */
  15685. public function __construct(array $vars, array $attributes = [])
  15686. {
  15687. $this->attributes = $attributes;
  15688. $this->vars = $vars;
  15689. }
  15690. public function getSubNodeNames(): array
  15691. {
  15692. return ['vars'];
  15693. }
  15694. public function getType(): string
  15695. {
  15696. return 'Stmt_Static';
  15697. }
  15698. }
  15699. <?php
  15700. declare (strict_types=1);
  15701. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15702. use PHPUnitPHAR\PhpParser\Node;
  15703. class Switch_ extends Node\Stmt
  15704. {
  15705. /** @var Node\Expr Condition */
  15706. public Node\Expr $cond;
  15707. /** @var Case_[] Case list */
  15708. public array $cases;
  15709. /**
  15710. * Constructs a case node.
  15711. *
  15712. * @param Node\Expr $cond Condition
  15713. * @param Case_[] $cases Case list
  15714. * @param array<string, mixed> $attributes Additional attributes
  15715. */
  15716. public function __construct(Node\Expr $cond, array $cases, array $attributes = [])
  15717. {
  15718. $this->attributes = $attributes;
  15719. $this->cond = $cond;
  15720. $this->cases = $cases;
  15721. }
  15722. public function getSubNodeNames(): array
  15723. {
  15724. return ['cond', 'cases'];
  15725. }
  15726. public function getType(): string
  15727. {
  15728. return 'Stmt_Switch';
  15729. }
  15730. }
  15731. <?php
  15732. declare (strict_types=1);
  15733. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15734. use PHPUnitPHAR\PhpParser\Node;
  15735. class TraitUse extends Node\Stmt
  15736. {
  15737. /** @var Node\Name[] Traits */
  15738. public array $traits;
  15739. /** @var TraitUseAdaptation[] Adaptations */
  15740. public array $adaptations;
  15741. /**
  15742. * Constructs a trait use node.
  15743. *
  15744. * @param Node\Name[] $traits Traits
  15745. * @param TraitUseAdaptation[] $adaptations Adaptations
  15746. * @param array<string, mixed> $attributes Additional attributes
  15747. */
  15748. public function __construct(array $traits, array $adaptations = [], array $attributes = [])
  15749. {
  15750. $this->attributes = $attributes;
  15751. $this->traits = $traits;
  15752. $this->adaptations = $adaptations;
  15753. }
  15754. public function getSubNodeNames(): array
  15755. {
  15756. return ['traits', 'adaptations'];
  15757. }
  15758. public function getType(): string
  15759. {
  15760. return 'Stmt_TraitUse';
  15761. }
  15762. }
  15763. <?php
  15764. declare (strict_types=1);
  15765. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15766. use PHPUnitPHAR\PhpParser\Node;
  15767. abstract class TraitUseAdaptation extends Node\Stmt
  15768. {
  15769. /** @var Node\Name|null Trait name */
  15770. public ?Node\Name $trait;
  15771. /** @var Node\Identifier Method name */
  15772. public Node\Identifier $method;
  15773. }
  15774. <?php
  15775. declare (strict_types=1);
  15776. namespace PHPUnitPHAR\PhpParser\Node\Stmt\TraitUseAdaptation;
  15777. use PHPUnitPHAR\PhpParser\Node;
  15778. class Alias extends Node\Stmt\TraitUseAdaptation
  15779. {
  15780. /** @var null|int New modifier */
  15781. public ?int $newModifier;
  15782. /** @var null|Node\Identifier New name */
  15783. public ?Node\Identifier $newName;
  15784. /**
  15785. * Constructs a trait use precedence adaptation node.
  15786. *
  15787. * @param null|Node\Name $trait Trait name
  15788. * @param string|Node\Identifier $method Method name
  15789. * @param null|int $newModifier New modifier
  15790. * @param null|string|Node\Identifier $newName New name
  15791. * @param array<string, mixed> $attributes Additional attributes
  15792. */
  15793. public function __construct(?Node\Name $trait, $method, ?int $newModifier, $newName, array $attributes = [])
  15794. {
  15795. $this->attributes = $attributes;
  15796. $this->trait = $trait;
  15797. $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
  15798. $this->newModifier = $newModifier;
  15799. $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName;
  15800. }
  15801. public function getSubNodeNames(): array
  15802. {
  15803. return ['trait', 'method', 'newModifier', 'newName'];
  15804. }
  15805. public function getType(): string
  15806. {
  15807. return 'Stmt_TraitUseAdaptation_Alias';
  15808. }
  15809. }
  15810. <?php
  15811. declare (strict_types=1);
  15812. namespace PHPUnitPHAR\PhpParser\Node\Stmt\TraitUseAdaptation;
  15813. use PHPUnitPHAR\PhpParser\Node;
  15814. class Precedence extends Node\Stmt\TraitUseAdaptation
  15815. {
  15816. /** @var Node\Name[] Overwritten traits */
  15817. public array $insteadof;
  15818. /**
  15819. * Constructs a trait use precedence adaptation node.
  15820. *
  15821. * @param Node\Name $trait Trait name
  15822. * @param string|Node\Identifier $method Method name
  15823. * @param Node\Name[] $insteadof Overwritten traits
  15824. * @param array<string, mixed> $attributes Additional attributes
  15825. */
  15826. public function __construct(Node\Name $trait, $method, array $insteadof, array $attributes = [])
  15827. {
  15828. $this->attributes = $attributes;
  15829. $this->trait = $trait;
  15830. $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
  15831. $this->insteadof = $insteadof;
  15832. }
  15833. public function getSubNodeNames(): array
  15834. {
  15835. return ['trait', 'method', 'insteadof'];
  15836. }
  15837. public function getType(): string
  15838. {
  15839. return 'Stmt_TraitUseAdaptation_Precedence';
  15840. }
  15841. }
  15842. <?php
  15843. declare (strict_types=1);
  15844. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15845. use PHPUnitPHAR\PhpParser\Node;
  15846. class Trait_ extends ClassLike
  15847. {
  15848. /**
  15849. * Constructs a trait node.
  15850. *
  15851. * @param string|Node\Identifier $name Name
  15852. * @param array{
  15853. * stmts?: Node\Stmt[],
  15854. * attrGroups?: Node\AttributeGroup[],
  15855. * } $subNodes Array of the following optional subnodes:
  15856. * 'stmts' => array(): Statements
  15857. * 'attrGroups' => array(): PHP attribute groups
  15858. * @param array<string, mixed> $attributes Additional attributes
  15859. */
  15860. public function __construct($name, array $subNodes = [], array $attributes = [])
  15861. {
  15862. $this->attributes = $attributes;
  15863. $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
  15864. $this->stmts = $subNodes['stmts'] ?? [];
  15865. $this->attrGroups = $subNodes['attrGroups'] ?? [];
  15866. }
  15867. public function getSubNodeNames(): array
  15868. {
  15869. return ['attrGroups', 'name', 'stmts'];
  15870. }
  15871. public function getType(): string
  15872. {
  15873. return 'Stmt_Trait';
  15874. }
  15875. }
  15876. <?php
  15877. declare (strict_types=1);
  15878. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15879. use PHPUnitPHAR\PhpParser\Node;
  15880. class TryCatch extends Node\Stmt
  15881. {
  15882. /** @var Node\Stmt[] Statements */
  15883. public array $stmts;
  15884. /** @var Catch_[] Catches */
  15885. public array $catches;
  15886. /** @var null|Finally_ Optional finally node */
  15887. public ?Finally_ $finally;
  15888. /**
  15889. * Constructs a try catch node.
  15890. *
  15891. * @param Node\Stmt[] $stmts Statements
  15892. * @param Catch_[] $catches Catches
  15893. * @param null|Finally_ $finally Optional finally node
  15894. * @param array<string, mixed> $attributes Additional attributes
  15895. */
  15896. public function __construct(array $stmts, array $catches, ?Finally_ $finally = null, array $attributes = [])
  15897. {
  15898. $this->attributes = $attributes;
  15899. $this->stmts = $stmts;
  15900. $this->catches = $catches;
  15901. $this->finally = $finally;
  15902. }
  15903. public function getSubNodeNames(): array
  15904. {
  15905. return ['stmts', 'catches', 'finally'];
  15906. }
  15907. public function getType(): string
  15908. {
  15909. return 'Stmt_TryCatch';
  15910. }
  15911. }
  15912. <?php
  15913. declare (strict_types=1);
  15914. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15915. use PHPUnitPHAR\PhpParser\Node;
  15916. class Unset_ extends Node\Stmt
  15917. {
  15918. /** @var Node\Expr[] Variables to unset */
  15919. public array $vars;
  15920. /**
  15921. * Constructs an unset node.
  15922. *
  15923. * @param Node\Expr[] $vars Variables to unset
  15924. * @param array<string, mixed> $attributes Additional attributes
  15925. */
  15926. public function __construct(array $vars, array $attributes = [])
  15927. {
  15928. $this->attributes = $attributes;
  15929. $this->vars = $vars;
  15930. }
  15931. public function getSubNodeNames(): array
  15932. {
  15933. return ['vars'];
  15934. }
  15935. public function getType(): string
  15936. {
  15937. return 'Stmt_Unset';
  15938. }
  15939. }
  15940. <?php
  15941. declare (strict_types=1);
  15942. namespace PHPUnitPHAR;
  15943. require __DIR__ . '/../UseItem.php';
  15944. <?php
  15945. declare (strict_types=1);
  15946. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15947. use PHPUnitPHAR\PhpParser\Node\Stmt;
  15948. use PHPUnitPHAR\PhpParser\Node\UseItem;
  15949. class Use_ extends Stmt
  15950. {
  15951. /**
  15952. * Unknown type. Both Stmt\Use_ / Stmt\GroupUse and Stmt\UseUse have a $type property, one of them will always be
  15953. * TYPE_UNKNOWN while the other has one of the three other possible types. For normal use statements the type on the
  15954. * Stmt\UseUse is unknown. It's only the other way around for mixed group use declarations.
  15955. */
  15956. public const TYPE_UNKNOWN = 0;
  15957. /** Class or namespace import */
  15958. public const TYPE_NORMAL = 1;
  15959. /** Function import */
  15960. public const TYPE_FUNCTION = 2;
  15961. /** Constant import */
  15962. public const TYPE_CONSTANT = 3;
  15963. /** @var self::TYPE_* Type of alias */
  15964. public int $type;
  15965. /** @var UseItem[] Aliases */
  15966. public array $uses;
  15967. /**
  15968. * Constructs an alias (use) list node.
  15969. *
  15970. * @param UseItem[] $uses Aliases
  15971. * @param Stmt\Use_::TYPE_* $type Type of alias
  15972. * @param array<string, mixed> $attributes Additional attributes
  15973. */
  15974. public function __construct(array $uses, int $type = self::TYPE_NORMAL, array $attributes = [])
  15975. {
  15976. $this->attributes = $attributes;
  15977. $this->type = $type;
  15978. $this->uses = $uses;
  15979. }
  15980. public function getSubNodeNames(): array
  15981. {
  15982. return ['type', 'uses'];
  15983. }
  15984. public function getType(): string
  15985. {
  15986. return 'Stmt_Use';
  15987. }
  15988. }
  15989. <?php
  15990. declare (strict_types=1);
  15991. namespace PHPUnitPHAR\PhpParser\Node\Stmt;
  15992. use PHPUnitPHAR\PhpParser\Node;
  15993. class While_ extends Node\Stmt
  15994. {
  15995. /** @var Node\Expr Condition */
  15996. public Node\Expr $cond;
  15997. /** @var Node\Stmt[] Statements */
  15998. public array $stmts;
  15999. /**
  16000. * Constructs a while node.
  16001. *
  16002. * @param Node\Expr $cond Condition
  16003. * @param Node\Stmt[] $stmts Statements
  16004. * @param array<string, mixed> $attributes Additional attributes
  16005. */
  16006. public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
  16007. {
  16008. $this->attributes = $attributes;
  16009. $this->cond = $cond;
  16010. $this->stmts = $stmts;
  16011. }
  16012. public function getSubNodeNames(): array
  16013. {
  16014. return ['cond', 'stmts'];
  16015. }
  16016. public function getType(): string
  16017. {
  16018. return 'Stmt_While';
  16019. }
  16020. }
  16021. <?php
  16022. declare (strict_types=1);
  16023. namespace PHPUnitPHAR\PhpParser\Node;
  16024. class UnionType extends ComplexType
  16025. {
  16026. /** @var (Identifier|Name|IntersectionType)[] Types */
  16027. public array $types;
  16028. /**
  16029. * Constructs a union type.
  16030. *
  16031. * @param (Identifier|Name|IntersectionType)[] $types Types
  16032. * @param array<string, mixed> $attributes Additional attributes
  16033. */
  16034. public function __construct(array $types, array $attributes = [])
  16035. {
  16036. $this->attributes = $attributes;
  16037. $this->types = $types;
  16038. }
  16039. public function getSubNodeNames(): array
  16040. {
  16041. return ['types'];
  16042. }
  16043. public function getType(): string
  16044. {
  16045. return 'UnionType';
  16046. }
  16047. }
  16048. <?php
  16049. declare (strict_types=1);
  16050. namespace PHPUnitPHAR\PhpParser\Node;
  16051. use PHPUnitPHAR\PhpParser\Node;
  16052. use PHPUnitPHAR\PhpParser\NodeAbstract;
  16053. use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
  16054. class UseItem extends NodeAbstract
  16055. {
  16056. /**
  16057. * @var Use_::TYPE_* One of the Stmt\Use_::TYPE_* constants. Will only differ from TYPE_UNKNOWN for mixed group uses
  16058. */
  16059. public int $type;
  16060. /** @var Node\Name Namespace, class, function or constant to alias */
  16061. public Name $name;
  16062. /** @var Identifier|null Alias */
  16063. public ?Identifier $alias;
  16064. /**
  16065. * Constructs an alias (use) item node.
  16066. *
  16067. * @param Node\Name $name Namespace/Class to alias
  16068. * @param null|string|Identifier $alias Alias
  16069. * @param Use_::TYPE_* $type Type of the use element (for mixed group use only)
  16070. * @param array<string, mixed> $attributes Additional attributes
  16071. */
  16072. public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = [])
  16073. {
  16074. $this->attributes = $attributes;
  16075. $this->type = $type;
  16076. $this->name = $name;
  16077. $this->alias = \is_string($alias) ? new Identifier($alias) : $alias;
  16078. }
  16079. public function getSubNodeNames(): array
  16080. {
  16081. return ['type', 'name', 'alias'];
  16082. }
  16083. /**
  16084. * Get alias. If not explicitly given this is the last component of the used name.
  16085. */
  16086. public function getAlias(): Identifier
  16087. {
  16088. if (null !== $this->alias) {
  16089. return $this->alias;
  16090. }
  16091. return new Identifier($this->name->getLast());
  16092. }
  16093. public function getType(): string
  16094. {
  16095. return 'UseItem';
  16096. }
  16097. }
  16098. // @deprecated compatibility alias
  16099. class_alias(UseItem::class, Stmt\UseUse::class);
  16100. <?php
  16101. declare (strict_types=1);
  16102. namespace PHPUnitPHAR\PhpParser\Node;
  16103. /**
  16104. * Represents a name that is written in source code with a leading dollar,
  16105. * but is not a proper variable. The leading dollar is not stored as part of the name.
  16106. *
  16107. * Examples: Names in property declarations are formatted as variables. Names in static property
  16108. * lookups are also formatted as variables.
  16109. */
  16110. class VarLikeIdentifier extends Identifier
  16111. {
  16112. public function getType(): string
  16113. {
  16114. return 'VarLikeIdentifier';
  16115. }
  16116. }
  16117. <?php
  16118. declare (strict_types=1);
  16119. namespace PHPUnitPHAR\PhpParser\Node;
  16120. use PHPUnitPHAR\PhpParser\NodeAbstract;
  16121. /**
  16122. * Represents the "..." in "foo(...)" of the first-class callable syntax.
  16123. */
  16124. class VariadicPlaceholder extends NodeAbstract
  16125. {
  16126. /**
  16127. * Create a variadic argument placeholder (first-class callable syntax).
  16128. *
  16129. * @param array<string, mixed> $attributes Additional attributes
  16130. */
  16131. public function __construct(array $attributes = [])
  16132. {
  16133. $this->attributes = $attributes;
  16134. }
  16135. public function getType(): string
  16136. {
  16137. return 'VariadicPlaceholder';
  16138. }
  16139. public function getSubNodeNames(): array
  16140. {
  16141. return [];
  16142. }
  16143. }
  16144. <?php
  16145. declare (strict_types=1);
  16146. namespace PHPUnitPHAR\PhpParser;
  16147. abstract class NodeAbstract implements Node, \JsonSerializable
  16148. {
  16149. /** @var array<string, mixed> Attributes */
  16150. protected array $attributes;
  16151. /**
  16152. * Creates a Node.
  16153. *
  16154. * @param array<string, mixed> $attributes Array of attributes
  16155. */
  16156. public function __construct(array $attributes = [])
  16157. {
  16158. $this->attributes = $attributes;
  16159. }
  16160. /**
  16161. * Gets line the node started in (alias of getStartLine).
  16162. *
  16163. * @return int Start line (or -1 if not available)
  16164. * @phpstan-return -1|positive-int
  16165. */
  16166. public function getLine(): int
  16167. {
  16168. return $this->attributes['startLine'] ?? -1;
  16169. }
  16170. /**
  16171. * Gets line the node started in.
  16172. *
  16173. * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
  16174. *
  16175. * @return int Start line (or -1 if not available)
  16176. * @phpstan-return -1|positive-int
  16177. */
  16178. public function getStartLine(): int
  16179. {
  16180. return $this->attributes['startLine'] ?? -1;
  16181. }
  16182. /**
  16183. * Gets the line the node ended in.
  16184. *
  16185. * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
  16186. *
  16187. * @return int End line (or -1 if not available)
  16188. * @phpstan-return -1|positive-int
  16189. */
  16190. public function getEndLine(): int
  16191. {
  16192. return $this->attributes['endLine'] ?? -1;
  16193. }
  16194. /**
  16195. * Gets the token offset of the first token that is part of this node.
  16196. *
  16197. * The offset is an index into the array returned by Lexer::getTokens().
  16198. *
  16199. * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  16200. *
  16201. * @return int Token start position (or -1 if not available)
  16202. */
  16203. public function getStartTokenPos(): int
  16204. {
  16205. return $this->attributes['startTokenPos'] ?? -1;
  16206. }
  16207. /**
  16208. * Gets the token offset of the last token that is part of this node.
  16209. *
  16210. * The offset is an index into the array returned by Lexer::getTokens().
  16211. *
  16212. * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
  16213. *
  16214. * @return int Token end position (or -1 if not available)
  16215. */
  16216. public function getEndTokenPos(): int
  16217. {
  16218. return $this->attributes['endTokenPos'] ?? -1;
  16219. }
  16220. /**
  16221. * Gets the file offset of the first character that is part of this node.
  16222. *
  16223. * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
  16224. *
  16225. * @return int File start position (or -1 if not available)
  16226. */
  16227. public function getStartFilePos(): int
  16228. {
  16229. return $this->attributes['startFilePos'] ?? -1;
  16230. }
  16231. /**
  16232. * Gets the file offset of the last character that is part of this node.
  16233. *
  16234. * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
  16235. *
  16236. * @return int File end position (or -1 if not available)
  16237. */
  16238. public function getEndFilePos(): int
  16239. {
  16240. return $this->attributes['endFilePos'] ?? -1;
  16241. }
  16242. /**
  16243. * Gets all comments directly preceding this node.
  16244. *
  16245. * The comments are also available through the "comments" attribute.
  16246. *
  16247. * @return Comment[]
  16248. */
  16249. public function getComments(): array
  16250. {
  16251. return $this->attributes['comments'] ?? [];
  16252. }
  16253. /**
  16254. * Gets the doc comment of the node.
  16255. *
  16256. * @return null|Comment\Doc Doc comment object or null
  16257. */
  16258. public function getDocComment(): ?Comment\Doc
  16259. {
  16260. $comments = $this->getComments();
  16261. for ($i = count($comments) - 1; $i >= 0; $i--) {
  16262. $comment = $comments[$i];
  16263. if ($comment instanceof Comment\Doc) {
  16264. return $comment;
  16265. }
  16266. }
  16267. return null;
  16268. }
  16269. /**
  16270. * Sets the doc comment of the node.
  16271. *
  16272. * This will either replace an existing doc comment or add it to the comments array.
  16273. *
  16274. * @param Comment\Doc $docComment Doc comment to set
  16275. */
  16276. public function setDocComment(Comment\Doc $docComment): void
  16277. {
  16278. $comments = $this->getComments();
  16279. for ($i = count($comments) - 1; $i >= 0; $i--) {
  16280. if ($comments[$i] instanceof Comment\Doc) {
  16281. // Replace existing doc comment.
  16282. $comments[$i] = $docComment;
  16283. $this->setAttribute('comments', $comments);
  16284. return;
  16285. }
  16286. }
  16287. // Append new doc comment.
  16288. $comments[] = $docComment;
  16289. $this->setAttribute('comments', $comments);
  16290. }
  16291. public function setAttribute(string $key, $value): void
  16292. {
  16293. $this->attributes[$key] = $value;
  16294. }
  16295. public function hasAttribute(string $key): bool
  16296. {
  16297. return array_key_exists($key, $this->attributes);
  16298. }
  16299. public function getAttribute(string $key, $default = null)
  16300. {
  16301. if (array_key_exists($key, $this->attributes)) {
  16302. return $this->attributes[$key];
  16303. }
  16304. return $default;
  16305. }
  16306. public function getAttributes(): array
  16307. {
  16308. return $this->attributes;
  16309. }
  16310. public function setAttributes(array $attributes): void
  16311. {
  16312. $this->attributes = $attributes;
  16313. }
  16314. /**
  16315. * @return array<string, mixed>
  16316. */
  16317. public function jsonSerialize(): array
  16318. {
  16319. return ['nodeType' => $this->getType()] + get_object_vars($this);
  16320. }
  16321. }
  16322. <?php
  16323. declare (strict_types=1);
  16324. namespace PHPUnitPHAR\PhpParser;
  16325. use PHPUnitPHAR\PhpParser\Node\Expr\Array_;
  16326. use PHPUnitPHAR\PhpParser\Node\Expr\Include_;
  16327. use PHPUnitPHAR\PhpParser\Node\Expr\List_;
  16328. use PHPUnitPHAR\PhpParser\Node\Scalar\Int_;
  16329. use PHPUnitPHAR\PhpParser\Node\Scalar\InterpolatedString;
  16330. use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
  16331. use PHPUnitPHAR\PhpParser\Node\Stmt\GroupUse;
  16332. use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
  16333. use PHPUnitPHAR\PhpParser\Node\UseItem;
  16334. class NodeDumper
  16335. {
  16336. private bool $dumpComments;
  16337. private bool $dumpPositions;
  16338. private bool $dumpOtherAttributes;
  16339. private ?string $code;
  16340. private string $res;
  16341. private string $nl;
  16342. private const IGNORE_ATTRIBUTES = ['comments' => \true, 'startLine' => \true, 'endLine' => \true, 'startFilePos' => \true, 'endFilePos' => \true, 'startTokenPos' => \true, 'endTokenPos' => \true];
  16343. /**
  16344. * Constructs a NodeDumper.
  16345. *
  16346. * Supported options:
  16347. * * bool dumpComments: Whether comments should be dumped.
  16348. * * bool dumpPositions: Whether line/offset information should be dumped. To dump offset
  16349. * information, the code needs to be passed to dump().
  16350. * * bool dumpOtherAttributes: Whether non-comment, non-position attributes should be dumped.
  16351. *
  16352. * @param array $options Options (see description)
  16353. */
  16354. public function __construct(array $options = [])
  16355. {
  16356. $this->dumpComments = !empty($options['dumpComments']);
  16357. $this->dumpPositions = !empty($options['dumpPositions']);
  16358. $this->dumpOtherAttributes = !empty($options['dumpOtherAttributes']);
  16359. }
  16360. /**
  16361. * Dumps a node or array.
  16362. *
  16363. * @param array|Node $node Node or array to dump
  16364. * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if
  16365. * the dumpPositions option is enabled and the dumping of node offsets
  16366. * is desired.
  16367. *
  16368. * @return string Dumped value
  16369. */
  16370. public function dump($node, ?string $code = null): string
  16371. {
  16372. $this->code = $code;
  16373. $this->res = '';
  16374. $this->nl = "\n";
  16375. $this->dumpRecursive($node, \false);
  16376. return $this->res;
  16377. }
  16378. /** @param mixed $node */
  16379. protected function dumpRecursive($node, bool $indent = \true): void
  16380. {
  16381. if ($indent) {
  16382. $this->nl .= " ";
  16383. }
  16384. if ($node instanceof Node) {
  16385. $this->res .= $node->getType();
  16386. if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) {
  16387. $this->res .= $p;
  16388. }
  16389. $this->res .= '(';
  16390. foreach ($node->getSubNodeNames() as $key) {
  16391. $this->res .= "{$this->nl} " . $key . ': ';
  16392. $value = $node->{$key};
  16393. if (\is_int($value)) {
  16394. if ('flags' === $key || 'newModifier' === $key) {
  16395. $this->res .= $this->dumpFlags($value);
  16396. continue;
  16397. }
  16398. if ('type' === $key && $node instanceof Include_) {
  16399. $this->res .= $this->dumpIncludeType($value);
  16400. continue;
  16401. }
  16402. if ('type' === $key && ($node instanceof Use_ || $node instanceof UseItem || $node instanceof GroupUse)) {
  16403. $this->res .= $this->dumpUseType($value);
  16404. continue;
  16405. }
  16406. }
  16407. $this->dumpRecursive($value);
  16408. }
  16409. if ($this->dumpComments && $comments = $node->getComments()) {
  16410. $this->res .= "{$this->nl} comments: ";
  16411. $this->dumpRecursive($comments);
  16412. }
  16413. if ($this->dumpOtherAttributes) {
  16414. foreach ($node->getAttributes() as $key => $value) {
  16415. if (isset(self::IGNORE_ATTRIBUTES[$key])) {
  16416. continue;
  16417. }
  16418. $this->res .= "{$this->nl} {$key}: ";
  16419. if (\is_int($value)) {
  16420. if ('kind' === $key) {
  16421. if ($node instanceof Int_) {
  16422. $this->res .= $this->dumpIntKind($value);
  16423. continue;
  16424. }
  16425. if ($node instanceof String_ || $node instanceof InterpolatedString) {
  16426. $this->res .= $this->dumpStringKind($value);
  16427. continue;
  16428. }
  16429. if ($node instanceof Array_) {
  16430. $this->res .= $this->dumpArrayKind($value);
  16431. continue;
  16432. }
  16433. if ($node instanceof List_) {
  16434. $this->res .= $this->dumpListKind($value);
  16435. continue;
  16436. }
  16437. }
  16438. }
  16439. $this->dumpRecursive($value);
  16440. }
  16441. }
  16442. $this->res .= "{$this->nl})";
  16443. } elseif (\is_array($node)) {
  16444. $this->res .= 'array(';
  16445. foreach ($node as $key => $value) {
  16446. $this->res .= "{$this->nl} " . $key . ': ';
  16447. $this->dumpRecursive($value);
  16448. }
  16449. $this->res .= "{$this->nl})";
  16450. } elseif ($node instanceof Comment) {
  16451. $this->res .= \str_replace("\n", $this->nl, $node->getReformattedText());
  16452. } elseif (\is_string($node)) {
  16453. $this->res .= \str_replace("\n", $this->nl, (string) $node);
  16454. } elseif (\is_int($node) || \is_float($node)) {
  16455. $this->res .= $node;
  16456. } elseif (null === $node) {
  16457. $this->res .= 'null';
  16458. } elseif (\false === $node) {
  16459. $this->res .= 'false';
  16460. } elseif (\true === $node) {
  16461. $this->res .= 'true';
  16462. } else {
  16463. throw new \InvalidArgumentException('Can only dump nodes and arrays.');
  16464. }
  16465. if ($indent) {
  16466. $this->nl = \substr($this->nl, 0, -4);
  16467. }
  16468. }
  16469. protected function dumpFlags(int $flags): string
  16470. {
  16471. $strs = [];
  16472. if ($flags & Modifiers::PUBLIC) {
  16473. $strs[] = 'PUBLIC';
  16474. }
  16475. if ($flags & Modifiers::PROTECTED) {
  16476. $strs[] = 'PROTECTED';
  16477. }
  16478. if ($flags & Modifiers::PRIVATE) {
  16479. $strs[] = 'PRIVATE';
  16480. }
  16481. if ($flags & Modifiers::ABSTRACT) {
  16482. $strs[] = 'ABSTRACT';
  16483. }
  16484. if ($flags & Modifiers::STATIC) {
  16485. $strs[] = 'STATIC';
  16486. }
  16487. if ($flags & Modifiers::FINAL) {
  16488. $strs[] = 'FINAL';
  16489. }
  16490. if ($flags & Modifiers::READONLY) {
  16491. $strs[] = 'READONLY';
  16492. }
  16493. if ($flags & Modifiers::PUBLIC_SET) {
  16494. $strs[] = 'PUBLIC_SET';
  16495. }
  16496. if ($flags & Modifiers::PROTECTED_SET) {
  16497. $strs[] = 'PROTECTED_SET';
  16498. }
  16499. if ($flags & Modifiers::PRIVATE_SET) {
  16500. $strs[] = 'PRIVATE_SET';
  16501. }
  16502. if ($strs) {
  16503. return implode(' | ', $strs) . ' (' . $flags . ')';
  16504. } else {
  16505. return (string) $flags;
  16506. }
  16507. }
  16508. /** @param array<int, string> $map */
  16509. private function dumpEnum(int $value, array $map): string
  16510. {
  16511. if (!isset($map[$value])) {
  16512. return (string) $value;
  16513. }
  16514. return $map[$value] . ' (' . $value . ')';
  16515. }
  16516. private function dumpIncludeType(int $type): string
  16517. {
  16518. return $this->dumpEnum($type, [Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE']);
  16519. }
  16520. private function dumpUseType(int $type): string
  16521. {
  16522. return $this->dumpEnum($type, [Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT']);
  16523. }
  16524. private function dumpIntKind(int $kind): string
  16525. {
  16526. return $this->dumpEnum($kind, [Int_::KIND_BIN => 'KIND_BIN', Int_::KIND_OCT => 'KIND_OCT', Int_::KIND_DEC => 'KIND_DEC', Int_::KIND_HEX => 'KIND_HEX']);
  16527. }
  16528. private function dumpStringKind(int $kind): string
  16529. {
  16530. return $this->dumpEnum($kind, [String_::KIND_SINGLE_QUOTED => 'KIND_SINGLE_QUOTED', String_::KIND_DOUBLE_QUOTED => 'KIND_DOUBLE_QUOTED', String_::KIND_HEREDOC => 'KIND_HEREDOC', String_::KIND_NOWDOC => 'KIND_NOWDOC']);
  16531. }
  16532. private function dumpArrayKind(int $kind): string
  16533. {
  16534. return $this->dumpEnum($kind, [Array_::KIND_LONG => 'KIND_LONG', Array_::KIND_SHORT => 'KIND_SHORT']);
  16535. }
  16536. private function dumpListKind(int $kind): string
  16537. {
  16538. return $this->dumpEnum($kind, [List_::KIND_LIST => 'KIND_LIST', List_::KIND_ARRAY => 'KIND_ARRAY']);
  16539. }
  16540. /**
  16541. * Dump node position, if possible.
  16542. *
  16543. * @param Node $node Node for which to dump position
  16544. *
  16545. * @return string|null Dump of position, or null if position information not available
  16546. */
  16547. protected function dumpPosition(Node $node): ?string
  16548. {
  16549. if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) {
  16550. return null;
  16551. }
  16552. $start = $node->getStartLine();
  16553. $end = $node->getEndLine();
  16554. if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') && null !== $this->code) {
  16555. $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos());
  16556. $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos());
  16557. }
  16558. return "[{$start} - {$end}]";
  16559. }
  16560. // Copied from Error class
  16561. private function toColumn(string $code, int $pos): int
  16562. {
  16563. if ($pos > strlen($code)) {
  16564. throw new \RuntimeException('Invalid position information');
  16565. }
  16566. $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
  16567. if (\false === $lineStartPos) {
  16568. $lineStartPos = -1;
  16569. }
  16570. return $pos - $lineStartPos;
  16571. }
  16572. }
  16573. <?php
  16574. declare (strict_types=1);
  16575. namespace PHPUnitPHAR\PhpParser;
  16576. use PHPUnitPHAR\PhpParser\NodeVisitor\FindingVisitor;
  16577. use PHPUnitPHAR\PhpParser\NodeVisitor\FirstFindingVisitor;
  16578. class NodeFinder
  16579. {
  16580. /**
  16581. * Find all nodes satisfying a filter callback.
  16582. *
  16583. * @param Node|Node[] $nodes Single node or array of nodes to search in
  16584. * @param callable $filter Filter callback: function(Node $node) : bool
  16585. *
  16586. * @return Node[] Found nodes satisfying the filter callback
  16587. */
  16588. public function find($nodes, callable $filter): array
  16589. {
  16590. if ($nodes === []) {
  16591. return [];
  16592. }
  16593. if (!is_array($nodes)) {
  16594. $nodes = [$nodes];
  16595. }
  16596. $visitor = new FindingVisitor($filter);
  16597. $traverser = new NodeTraverser($visitor);
  16598. $traverser->traverse($nodes);
  16599. return $visitor->getFoundNodes();
  16600. }
  16601. /**
  16602. * Find all nodes that are instances of a certain class.
  16603. * @template TNode as Node
  16604. *
  16605. * @param Node|Node[] $nodes Single node or array of nodes to search in
  16606. * @param class-string<TNode> $class Class name
  16607. *
  16608. * @return TNode[] Found nodes (all instances of $class)
  16609. */
  16610. public function findInstanceOf($nodes, string $class): array
  16611. {
  16612. return $this->find($nodes, function ($node) use ($class) {
  16613. return $node instanceof $class;
  16614. });
  16615. }
  16616. /**
  16617. * Find first node satisfying a filter callback.
  16618. *
  16619. * @param Node|Node[] $nodes Single node or array of nodes to search in
  16620. * @param callable $filter Filter callback: function(Node $node) : bool
  16621. *
  16622. * @return null|Node Found node (or null if none found)
  16623. */
  16624. public function findFirst($nodes, callable $filter): ?Node
  16625. {
  16626. if ($nodes === []) {
  16627. return null;
  16628. }
  16629. if (!is_array($nodes)) {
  16630. $nodes = [$nodes];
  16631. }
  16632. $visitor = new FirstFindingVisitor($filter);
  16633. $traverser = new NodeTraverser($visitor);
  16634. $traverser->traverse($nodes);
  16635. return $visitor->getFoundNode();
  16636. }
  16637. /**
  16638. * Find first node that is an instance of a certain class.
  16639. *
  16640. * @template TNode as Node
  16641. *
  16642. * @param Node|Node[] $nodes Single node or array of nodes to search in
  16643. * @param class-string<TNode> $class Class name
  16644. *
  16645. * @return null|TNode Found node, which is an instance of $class (or null if none found)
  16646. */
  16647. public function findFirstInstanceOf($nodes, string $class): ?Node
  16648. {
  16649. return $this->findFirst($nodes, function ($node) use ($class) {
  16650. return $node instanceof $class;
  16651. });
  16652. }
  16653. }
  16654. <?php
  16655. declare (strict_types=1);
  16656. namespace PHPUnitPHAR\PhpParser;
  16657. class NodeTraverser implements NodeTraverserInterface
  16658. {
  16659. /**
  16660. * @deprecated Use NodeVisitor::DONT_TRAVERSE_CHILDREN instead.
  16661. */
  16662. public const DONT_TRAVERSE_CHILDREN = NodeVisitor::DONT_TRAVERSE_CHILDREN;
  16663. /**
  16664. * @deprecated Use NodeVisitor::STOP_TRAVERSAL instead.
  16665. */
  16666. public const STOP_TRAVERSAL = NodeVisitor::STOP_TRAVERSAL;
  16667. /**
  16668. * @deprecated Use NodeVisitor::REMOVE_NODE instead.
  16669. */
  16670. public const REMOVE_NODE = NodeVisitor::REMOVE_NODE;
  16671. /**
  16672. * @deprecated Use NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN instead.
  16673. */
  16674. public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
  16675. /** @var list<NodeVisitor> Visitors */
  16676. protected array $visitors = [];
  16677. /** @var bool Whether traversal should be stopped */
  16678. protected bool $stopTraversal;
  16679. /**
  16680. * Create a traverser with the given visitors.
  16681. *
  16682. * @param NodeVisitor ...$visitors Node visitors
  16683. */
  16684. public function __construct(NodeVisitor ...$visitors)
  16685. {
  16686. $this->visitors = $visitors;
  16687. }
  16688. /**
  16689. * Adds a visitor.
  16690. *
  16691. * @param NodeVisitor $visitor Visitor to add
  16692. */
  16693. public function addVisitor(NodeVisitor $visitor): void
  16694. {
  16695. $this->visitors[] = $visitor;
  16696. }
  16697. /**
  16698. * Removes an added visitor.
  16699. */
  16700. public function removeVisitor(NodeVisitor $visitor): void
  16701. {
  16702. $index = array_search($visitor, $this->visitors);
  16703. if ($index !== \false) {
  16704. array_splice($this->visitors, $index, 1, []);
  16705. }
  16706. }
  16707. /**
  16708. * Traverses an array of nodes using the registered visitors.
  16709. *
  16710. * @param Node[] $nodes Array of nodes
  16711. *
  16712. * @return Node[] Traversed array of nodes
  16713. */
  16714. public function traverse(array $nodes): array
  16715. {
  16716. $this->stopTraversal = \false;
  16717. foreach ($this->visitors as $visitor) {
  16718. if (null !== $return = $visitor->beforeTraverse($nodes)) {
  16719. $nodes = $return;
  16720. }
  16721. }
  16722. $nodes = $this->traverseArray($nodes);
  16723. for ($i = \count($this->visitors) - 1; $i >= 0; --$i) {
  16724. $visitor = $this->visitors[$i];
  16725. if (null !== $return = $visitor->afterTraverse($nodes)) {
  16726. $nodes = $return;
  16727. }
  16728. }
  16729. return $nodes;
  16730. }
  16731. /**
  16732. * Recursively traverse a node.
  16733. *
  16734. * @param Node $node Node to traverse.
  16735. */
  16736. protected function traverseNode(Node $node): void
  16737. {
  16738. foreach ($node->getSubNodeNames() as $name) {
  16739. $subNode = $node->{$name};
  16740. if (\is_array($subNode)) {
  16741. $node->{$name} = $this->traverseArray($subNode);
  16742. if ($this->stopTraversal) {
  16743. break;
  16744. }
  16745. } elseif ($subNode instanceof Node) {
  16746. $traverseChildren = \true;
  16747. $visitorIndex = -1;
  16748. foreach ($this->visitors as $visitorIndex => $visitor) {
  16749. $return = $visitor->enterNode($subNode);
  16750. if (null !== $return) {
  16751. if ($return instanceof Node) {
  16752. $this->ensureReplacementReasonable($subNode, $return);
  16753. $subNode = $node->{$name} = $return;
  16754. } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
  16755. $traverseChildren = \false;
  16756. } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
  16757. $traverseChildren = \false;
  16758. break;
  16759. } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
  16760. $this->stopTraversal = \true;
  16761. break 2;
  16762. } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
  16763. $node->{$name} = null;
  16764. continue 2;
  16765. } else {
  16766. throw new \LogicException('enterNode() returned invalid value of type ' . gettype($return));
  16767. }
  16768. }
  16769. }
  16770. if ($traverseChildren) {
  16771. $this->traverseNode($subNode);
  16772. if ($this->stopTraversal) {
  16773. break;
  16774. }
  16775. }
  16776. for (; $visitorIndex >= 0; --$visitorIndex) {
  16777. $visitor = $this->visitors[$visitorIndex];
  16778. $return = $visitor->leaveNode($subNode);
  16779. if (null !== $return) {
  16780. if ($return instanceof Node) {
  16781. $this->ensureReplacementReasonable($subNode, $return);
  16782. $subNode = $node->{$name} = $return;
  16783. } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
  16784. $this->stopTraversal = \true;
  16785. break 2;
  16786. } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
  16787. $node->{$name} = null;
  16788. break;
  16789. } elseif (\is_array($return)) {
  16790. throw new \LogicException('leaveNode() may only return an array ' . 'if the parent structure is an array');
  16791. } else {
  16792. throw new \LogicException('leaveNode() returned invalid value of type ' . gettype($return));
  16793. }
  16794. }
  16795. }
  16796. }
  16797. }
  16798. }
  16799. /**
  16800. * Recursively traverse array (usually of nodes).
  16801. *
  16802. * @param array $nodes Array to traverse
  16803. *
  16804. * @return array Result of traversal (may be original array or changed one)
  16805. */
  16806. protected function traverseArray(array $nodes): array
  16807. {
  16808. $doNodes = [];
  16809. foreach ($nodes as $i => $node) {
  16810. if ($node instanceof Node) {
  16811. $traverseChildren = \true;
  16812. $visitorIndex = -1;
  16813. foreach ($this->visitors as $visitorIndex => $visitor) {
  16814. $return = $visitor->enterNode($node);
  16815. if (null !== $return) {
  16816. if ($return instanceof Node) {
  16817. $this->ensureReplacementReasonable($node, $return);
  16818. $nodes[$i] = $node = $return;
  16819. } elseif (\is_array($return)) {
  16820. $doNodes[] = [$i, $return];
  16821. continue 2;
  16822. } elseif (NodeVisitor::REMOVE_NODE === $return) {
  16823. $doNodes[] = [$i, []];
  16824. continue 2;
  16825. } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
  16826. $traverseChildren = \false;
  16827. } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
  16828. $traverseChildren = \false;
  16829. break;
  16830. } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
  16831. $this->stopTraversal = \true;
  16832. break 2;
  16833. } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
  16834. throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array');
  16835. } else {
  16836. throw new \LogicException('enterNode() returned invalid value of type ' . gettype($return));
  16837. }
  16838. }
  16839. }
  16840. if ($traverseChildren) {
  16841. $this->traverseNode($node);
  16842. if ($this->stopTraversal) {
  16843. break;
  16844. }
  16845. }
  16846. for (; $visitorIndex >= 0; --$visitorIndex) {
  16847. $visitor = $this->visitors[$visitorIndex];
  16848. $return = $visitor->leaveNode($node);
  16849. if (null !== $return) {
  16850. if ($return instanceof Node) {
  16851. $this->ensureReplacementReasonable($node, $return);
  16852. $nodes[$i] = $node = $return;
  16853. } elseif (\is_array($return)) {
  16854. $doNodes[] = [$i, $return];
  16855. break;
  16856. } elseif (NodeVisitor::REMOVE_NODE === $return) {
  16857. $doNodes[] = [$i, []];
  16858. break;
  16859. } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
  16860. $this->stopTraversal = \true;
  16861. break 2;
  16862. } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
  16863. throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array');
  16864. } else {
  16865. throw new \LogicException('leaveNode() returned invalid value of type ' . gettype($return));
  16866. }
  16867. }
  16868. }
  16869. } elseif (\is_array($node)) {
  16870. throw new \LogicException('Invalid node structure: Contains nested arrays');
  16871. }
  16872. }
  16873. if (!empty($doNodes)) {
  16874. while (list($i, $replace) = array_pop($doNodes)) {
  16875. array_splice($nodes, $i, 1, $replace);
  16876. }
  16877. }
  16878. return $nodes;
  16879. }
  16880. private function ensureReplacementReasonable(Node $old, Node $new): void
  16881. {
  16882. if ($old instanceof Node\Stmt && $new instanceof Node\Expr) {
  16883. throw new \LogicException("Trying to replace statement ({$old->getType()}) " . "with expression ({$new->getType()}). Are you missing a " . "Stmt_Expression wrapper?");
  16884. }
  16885. if ($old instanceof Node\Expr && $new instanceof Node\Stmt) {
  16886. throw new \LogicException("Trying to replace expression ({$old->getType()}) " . "with statement ({$new->getType()})");
  16887. }
  16888. }
  16889. }
  16890. <?php
  16891. declare (strict_types=1);
  16892. namespace PHPUnitPHAR\PhpParser;
  16893. interface NodeTraverserInterface
  16894. {
  16895. /**
  16896. * Adds a visitor.
  16897. *
  16898. * @param NodeVisitor $visitor Visitor to add
  16899. */
  16900. public function addVisitor(NodeVisitor $visitor): void;
  16901. /**
  16902. * Removes an added visitor.
  16903. */
  16904. public function removeVisitor(NodeVisitor $visitor): void;
  16905. /**
  16906. * Traverses an array of nodes using the registered visitors.
  16907. *
  16908. * @param Node[] $nodes Array of nodes
  16909. *
  16910. * @return Node[] Traversed array of nodes
  16911. */
  16912. public function traverse(array $nodes): array;
  16913. }
  16914. <?php
  16915. declare (strict_types=1);
  16916. namespace PHPUnitPHAR\PhpParser;
  16917. interface NodeVisitor
  16918. {
  16919. /**
  16920. * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes
  16921. * of the current node will not be traversed for any visitors.
  16922. *
  16923. * For subsequent visitors enterNode() will still be called on the current
  16924. * node and leaveNode() will also be invoked for the current node.
  16925. */
  16926. public const DONT_TRAVERSE_CHILDREN = 1;
  16927. /**
  16928. * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns
  16929. * STOP_TRAVERSAL, traversal is aborted.
  16930. *
  16931. * The afterTraverse() method will still be invoked.
  16932. */
  16933. public const STOP_TRAVERSAL = 2;
  16934. /**
  16935. * If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs
  16936. * in an array, it will be removed from the array.
  16937. *
  16938. * For subsequent visitors leaveNode() will still be invoked for the
  16939. * removed node.
  16940. */
  16941. public const REMOVE_NODE = 3;
  16942. /**
  16943. * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes
  16944. * of the current node will not be traversed for any visitors.
  16945. *
  16946. * For subsequent visitors enterNode() will not be called as well.
  16947. * leaveNode() will be invoked for visitors that has enterNode() method invoked.
  16948. */
  16949. public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4;
  16950. /**
  16951. * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns REPLACE_WITH_NULL,
  16952. * the node will be replaced with null. This is not a legal return value if the node is part
  16953. * of an array, rather than another node.
  16954. */
  16955. public const REPLACE_WITH_NULL = 5;
  16956. /**
  16957. * Called once before traversal.
  16958. *
  16959. * Return value semantics:
  16960. * * null: $nodes stays as-is
  16961. * * otherwise: $nodes is set to the return value
  16962. *
  16963. * @param Node[] $nodes Array of nodes
  16964. *
  16965. * @return null|Node[] Array of nodes
  16966. */
  16967. public function beforeTraverse(array $nodes);
  16968. /**
  16969. * Called when entering a node.
  16970. *
  16971. * Return value semantics:
  16972. * * null
  16973. * => $node stays as-is
  16974. * * array (of Nodes)
  16975. * => The return value is merged into the parent array (at the position of the $node)
  16976. * * NodeVisitor::REMOVE_NODE
  16977. * => $node is removed from the parent array
  16978. * * NodeVisitor::REPLACE_WITH_NULL
  16979. * => $node is replaced with null
  16980. * * NodeVisitor::DONT_TRAVERSE_CHILDREN
  16981. * => Children of $node are not traversed. $node stays as-is
  16982. * * NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
  16983. * => Further visitors for the current node are skipped, and its children are not
  16984. * traversed. $node stays as-is.
  16985. * * NodeVisitor::STOP_TRAVERSAL
  16986. * => Traversal is aborted. $node stays as-is
  16987. * * otherwise
  16988. * => $node is set to the return value
  16989. *
  16990. * @param Node $node Node
  16991. *
  16992. * @return null|int|Node|Node[] Replacement node (or special return value)
  16993. */
  16994. public function enterNode(Node $node);
  16995. /**
  16996. * Called when leaving a node.
  16997. *
  16998. * Return value semantics:
  16999. * * null
  17000. * => $node stays as-is
  17001. * * NodeVisitor::REMOVE_NODE
  17002. * => $node is removed from the parent array
  17003. * * NodeVisitor::REPLACE_WITH_NULL
  17004. * => $node is replaced with null
  17005. * * NodeVisitor::STOP_TRAVERSAL
  17006. * => Traversal is aborted. $node stays as-is
  17007. * * array (of Nodes)
  17008. * => The return value is merged into the parent array (at the position of the $node)
  17009. * * otherwise
  17010. * => $node is set to the return value
  17011. *
  17012. * @param Node $node Node
  17013. *
  17014. * @return null|int|Node|Node[] Replacement node (or special return value)
  17015. */
  17016. public function leaveNode(Node $node);
  17017. /**
  17018. * Called once after traversal.
  17019. *
  17020. * Return value semantics:
  17021. * * null: $nodes stays as-is
  17022. * * otherwise: $nodes is set to the return value
  17023. *
  17024. * @param Node[] $nodes Array of nodes
  17025. *
  17026. * @return null|Node[] Array of nodes
  17027. */
  17028. public function afterTraverse(array $nodes);
  17029. }
  17030. <?php
  17031. declare (strict_types=1);
  17032. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17033. use PHPUnitPHAR\PhpParser\Node;
  17034. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17035. /**
  17036. * Visitor cloning all nodes and linking to the original nodes using an attribute.
  17037. *
  17038. * This visitor is required to perform format-preserving pretty prints.
  17039. */
  17040. class CloningVisitor extends NodeVisitorAbstract
  17041. {
  17042. public function enterNode(Node $origNode)
  17043. {
  17044. $node = clone $origNode;
  17045. $node->setAttribute('origNode', $origNode);
  17046. return $node;
  17047. }
  17048. }
  17049. <?php
  17050. declare (strict_types=1);
  17051. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17052. use PHPUnitPHAR\PhpParser\Comment;
  17053. use PHPUnitPHAR\PhpParser\Node;
  17054. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17055. use PHPUnitPHAR\PhpParser\Token;
  17056. class CommentAnnotatingVisitor extends NodeVisitorAbstract
  17057. {
  17058. /** @var int Last seen token start position */
  17059. private int $pos = 0;
  17060. /** @var Token[] Token array */
  17061. private array $tokens;
  17062. /** @var list<int> Token positions of comments */
  17063. private array $commentPositions = [];
  17064. /**
  17065. * Create a comment annotation visitor.
  17066. *
  17067. * @param Token[] $tokens Token array
  17068. */
  17069. public function __construct(array $tokens)
  17070. {
  17071. $this->tokens = $tokens;
  17072. // Collect positions of comments. We use this to avoid traversing parts of the AST where
  17073. // there are no comments.
  17074. foreach ($tokens as $i => $token) {
  17075. if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) {
  17076. $this->commentPositions[] = $i;
  17077. }
  17078. }
  17079. }
  17080. public function enterNode(Node $node)
  17081. {
  17082. $nextCommentPos = current($this->commentPositions);
  17083. if ($nextCommentPos === \false) {
  17084. // No more comments.
  17085. return self::STOP_TRAVERSAL;
  17086. }
  17087. $oldPos = $this->pos;
  17088. $this->pos = $pos = $node->getStartTokenPos();
  17089. if ($nextCommentPos > $oldPos && $nextCommentPos < $pos) {
  17090. $comments = [];
  17091. while (--$pos >= $oldPos) {
  17092. $token = $this->tokens[$pos];
  17093. if ($token->id === \T_DOC_COMMENT) {
  17094. $comments[] = new Comment\Doc($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos);
  17095. continue;
  17096. }
  17097. if ($token->id === \T_COMMENT) {
  17098. $comments[] = new Comment($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos);
  17099. continue;
  17100. }
  17101. if ($token->id !== \T_WHITESPACE) {
  17102. break;
  17103. }
  17104. }
  17105. if (!empty($comments)) {
  17106. $node->setAttribute('comments', array_reverse($comments));
  17107. }
  17108. do {
  17109. $nextCommentPos = next($this->commentPositions);
  17110. } while ($nextCommentPos !== \false && $nextCommentPos < $this->pos);
  17111. }
  17112. $endPos = $node->getEndTokenPos();
  17113. if ($nextCommentPos > $endPos) {
  17114. // Skip children if there are no comments located inside this node.
  17115. $this->pos = $endPos;
  17116. return self::DONT_TRAVERSE_CHILDREN;
  17117. }
  17118. return null;
  17119. }
  17120. }
  17121. <?php
  17122. declare (strict_types=1);
  17123. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17124. use PHPUnitPHAR\PhpParser\Node;
  17125. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17126. /**
  17127. * This visitor can be used to find and collect all nodes satisfying some criterion determined by
  17128. * a filter callback.
  17129. */
  17130. class FindingVisitor extends NodeVisitorAbstract
  17131. {
  17132. /** @var callable Filter callback */
  17133. protected $filterCallback;
  17134. /** @var Node[] Found nodes */
  17135. protected array $foundNodes;
  17136. public function __construct(callable $filterCallback)
  17137. {
  17138. $this->filterCallback = $filterCallback;
  17139. }
  17140. /**
  17141. * Get found nodes satisfying the filter callback.
  17142. *
  17143. * Nodes are returned in pre-order.
  17144. *
  17145. * @return Node[] Found nodes
  17146. */
  17147. public function getFoundNodes(): array
  17148. {
  17149. return $this->foundNodes;
  17150. }
  17151. public function beforeTraverse(array $nodes): ?array
  17152. {
  17153. $this->foundNodes = [];
  17154. return null;
  17155. }
  17156. public function enterNode(Node $node)
  17157. {
  17158. $filterCallback = $this->filterCallback;
  17159. if ($filterCallback($node)) {
  17160. $this->foundNodes[] = $node;
  17161. }
  17162. return null;
  17163. }
  17164. }
  17165. <?php
  17166. declare (strict_types=1);
  17167. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17168. use PHPUnitPHAR\PhpParser\Node;
  17169. use PHPUnitPHAR\PhpParser\NodeVisitor;
  17170. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17171. /**
  17172. * This visitor can be used to find the first node satisfying some criterion determined by
  17173. * a filter callback.
  17174. */
  17175. class FirstFindingVisitor extends NodeVisitorAbstract
  17176. {
  17177. /** @var callable Filter callback */
  17178. protected $filterCallback;
  17179. /** @var null|Node Found node */
  17180. protected ?Node $foundNode;
  17181. public function __construct(callable $filterCallback)
  17182. {
  17183. $this->filterCallback = $filterCallback;
  17184. }
  17185. /**
  17186. * Get found node satisfying the filter callback.
  17187. *
  17188. * Returns null if no node satisfies the filter callback.
  17189. *
  17190. * @return null|Node Found node (or null if not found)
  17191. */
  17192. public function getFoundNode(): ?Node
  17193. {
  17194. return $this->foundNode;
  17195. }
  17196. public function beforeTraverse(array $nodes): ?array
  17197. {
  17198. $this->foundNode = null;
  17199. return null;
  17200. }
  17201. public function enterNode(Node $node)
  17202. {
  17203. $filterCallback = $this->filterCallback;
  17204. if ($filterCallback($node)) {
  17205. $this->foundNode = $node;
  17206. return NodeVisitor::STOP_TRAVERSAL;
  17207. }
  17208. return null;
  17209. }
  17210. }
  17211. <?php
  17212. declare (strict_types=1);
  17213. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17214. use PHPUnitPHAR\PhpParser\ErrorHandler;
  17215. use PHPUnitPHAR\PhpParser\NameContext;
  17216. use PHPUnitPHAR\PhpParser\Node;
  17217. use PHPUnitPHAR\PhpParser\Node\Expr;
  17218. use PHPUnitPHAR\PhpParser\Node\Name;
  17219. use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
  17220. use PHPUnitPHAR\PhpParser\Node\Stmt;
  17221. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17222. class NameResolver extends NodeVisitorAbstract
  17223. {
  17224. /** @var NameContext Naming context */
  17225. protected NameContext $nameContext;
  17226. /** @var bool Whether to preserve original names */
  17227. protected bool $preserveOriginalNames;
  17228. /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */
  17229. protected bool $replaceNodes;
  17230. /**
  17231. * Constructs a name resolution visitor.
  17232. *
  17233. * Options:
  17234. * * preserveOriginalNames (default false): An "originalName" attribute will be added to
  17235. * all name nodes that underwent resolution.
  17236. * * replaceNodes (default true): Resolved names are replaced in-place. Otherwise, a
  17237. * resolvedName attribute is added. (Names that cannot be statically resolved receive a
  17238. * namespacedName attribute, as usual.)
  17239. *
  17240. * @param ErrorHandler|null $errorHandler Error handler
  17241. * @param array{preserveOriginalNames?: bool, replaceNodes?: bool} $options Options
  17242. */
  17243. public function __construct(?ErrorHandler $errorHandler = null, array $options = [])
  17244. {
  17245. $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing());
  17246. $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? \false;
  17247. $this->replaceNodes = $options['replaceNodes'] ?? \true;
  17248. }
  17249. /**
  17250. * Get name resolution context.
  17251. */
  17252. public function getNameContext(): NameContext
  17253. {
  17254. return $this->nameContext;
  17255. }
  17256. public function beforeTraverse(array $nodes): ?array
  17257. {
  17258. $this->nameContext->startNamespace();
  17259. return null;
  17260. }
  17261. public function enterNode(Node $node)
  17262. {
  17263. if ($node instanceof Stmt\Namespace_) {
  17264. $this->nameContext->startNamespace($node->name);
  17265. } elseif ($node instanceof Stmt\Use_) {
  17266. foreach ($node->uses as $use) {
  17267. $this->addAlias($use, $node->type, null);
  17268. }
  17269. } elseif ($node instanceof Stmt\GroupUse) {
  17270. foreach ($node->uses as $use) {
  17271. $this->addAlias($use, $node->type, $node->prefix);
  17272. }
  17273. } elseif ($node instanceof Stmt\Class_) {
  17274. if (null !== $node->extends) {
  17275. $node->extends = $this->resolveClassName($node->extends);
  17276. }
  17277. foreach ($node->implements as &$interface) {
  17278. $interface = $this->resolveClassName($interface);
  17279. }
  17280. $this->resolveAttrGroups($node);
  17281. if (null !== $node->name) {
  17282. $this->addNamespacedName($node);
  17283. } else {
  17284. $node->namespacedName = null;
  17285. }
  17286. } elseif ($node instanceof Stmt\Interface_) {
  17287. foreach ($node->extends as &$interface) {
  17288. $interface = $this->resolveClassName($interface);
  17289. }
  17290. $this->resolveAttrGroups($node);
  17291. $this->addNamespacedName($node);
  17292. } elseif ($node instanceof Stmt\Enum_) {
  17293. foreach ($node->implements as &$interface) {
  17294. $interface = $this->resolveClassName($interface);
  17295. }
  17296. $this->resolveAttrGroups($node);
  17297. $this->addNamespacedName($node);
  17298. } elseif ($node instanceof Stmt\Trait_) {
  17299. $this->resolveAttrGroups($node);
  17300. $this->addNamespacedName($node);
  17301. } elseif ($node instanceof Stmt\Function_) {
  17302. $this->resolveSignature($node);
  17303. $this->resolveAttrGroups($node);
  17304. $this->addNamespacedName($node);
  17305. } elseif ($node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure || $node instanceof Expr\ArrowFunction) {
  17306. $this->resolveSignature($node);
  17307. $this->resolveAttrGroups($node);
  17308. } elseif ($node instanceof Stmt\Property) {
  17309. if (null !== $node->type) {
  17310. $node->type = $this->resolveType($node->type);
  17311. }
  17312. $this->resolveAttrGroups($node);
  17313. } elseif ($node instanceof Node\PropertyHook) {
  17314. foreach ($node->params as $param) {
  17315. $param->type = $this->resolveType($param->type);
  17316. $this->resolveAttrGroups($param);
  17317. }
  17318. $this->resolveAttrGroups($node);
  17319. } elseif ($node instanceof Stmt\Const_) {
  17320. foreach ($node->consts as $const) {
  17321. $this->addNamespacedName($const);
  17322. }
  17323. } elseif ($node instanceof Stmt\ClassConst) {
  17324. if (null !== $node->type) {
  17325. $node->type = $this->resolveType($node->type);
  17326. }
  17327. $this->resolveAttrGroups($node);
  17328. } elseif ($node instanceof Stmt\EnumCase) {
  17329. $this->resolveAttrGroups($node);
  17330. } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) {
  17331. if ($node->class instanceof Name) {
  17332. $node->class = $this->resolveClassName($node->class);
  17333. }
  17334. } elseif ($node instanceof Stmt\Catch_) {
  17335. foreach ($node->types as &$type) {
  17336. $type = $this->resolveClassName($type);
  17337. }
  17338. } elseif ($node instanceof Expr\FuncCall) {
  17339. if ($node->name instanceof Name) {
  17340. $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION);
  17341. }
  17342. } elseif ($node instanceof Expr\ConstFetch) {
  17343. $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT);
  17344. } elseif ($node instanceof Stmt\TraitUse) {
  17345. foreach ($node->traits as &$trait) {
  17346. $trait = $this->resolveClassName($trait);
  17347. }
  17348. foreach ($node->adaptations as $adaptation) {
  17349. if (null !== $adaptation->trait) {
  17350. $adaptation->trait = $this->resolveClassName($adaptation->trait);
  17351. }
  17352. if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) {
  17353. foreach ($adaptation->insteadof as &$insteadof) {
  17354. $insteadof = $this->resolveClassName($insteadof);
  17355. }
  17356. }
  17357. }
  17358. }
  17359. return null;
  17360. }
  17361. /** @param Stmt\Use_::TYPE_* $type */
  17362. private function addAlias(Node\UseItem $use, int $type, ?Name $prefix = null): void
  17363. {
  17364. // Add prefix for group uses
  17365. $name = $prefix ? Name::concat($prefix, $use->name) : $use->name;
  17366. // Type is determined either by individual element or whole use declaration
  17367. $type |= $use->type;
  17368. $this->nameContext->addAlias($name, (string) $use->getAlias(), $type, $use->getAttributes());
  17369. }
  17370. /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure|Expr\ArrowFunction $node */
  17371. private function resolveSignature($node): void
  17372. {
  17373. foreach ($node->params as $param) {
  17374. $param->type = $this->resolveType($param->type);
  17375. $this->resolveAttrGroups($param);
  17376. }
  17377. $node->returnType = $this->resolveType($node->returnType);
  17378. }
  17379. /**
  17380. * @template T of Node\Identifier|Name|Node\ComplexType|null
  17381. * @param T $node
  17382. * @return T
  17383. */
  17384. private function resolveType(?Node $node): ?Node
  17385. {
  17386. if ($node instanceof Name) {
  17387. return $this->resolveClassName($node);
  17388. }
  17389. if ($node instanceof Node\NullableType) {
  17390. $node->type = $this->resolveType($node->type);
  17391. return $node;
  17392. }
  17393. if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
  17394. foreach ($node->types as &$type) {
  17395. $type = $this->resolveType($type);
  17396. }
  17397. return $node;
  17398. }
  17399. return $node;
  17400. }
  17401. /**
  17402. * Resolve name, according to name resolver options.
  17403. *
  17404. * @param Name $name Function or constant name to resolve
  17405. * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
  17406. *
  17407. * @return Name Resolved name, or original name with attribute
  17408. */
  17409. protected function resolveName(Name $name, int $type): Name
  17410. {
  17411. if (!$this->replaceNodes) {
  17412. $resolvedName = $this->nameContext->getResolvedName($name, $type);
  17413. if (null !== $resolvedName) {
  17414. $name->setAttribute('resolvedName', $resolvedName);
  17415. } else {
  17416. $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
  17417. }
  17418. return $name;
  17419. }
  17420. if ($this->preserveOriginalNames) {
  17421. // Save the original name
  17422. $originalName = $name;
  17423. $name = clone $originalName;
  17424. $name->setAttribute('originalName', $originalName);
  17425. }
  17426. $resolvedName = $this->nameContext->getResolvedName($name, $type);
  17427. if (null !== $resolvedName) {
  17428. return $resolvedName;
  17429. }
  17430. // unqualified names inside a namespace cannot be resolved at compile-time
  17431. // add the namespaced version of the name as an attribute
  17432. $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
  17433. return $name;
  17434. }
  17435. protected function resolveClassName(Name $name): Name
  17436. {
  17437. return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL);
  17438. }
  17439. protected function addNamespacedName(Node $node): void
  17440. {
  17441. $node->namespacedName = Name::concat($this->nameContext->getNamespace(), (string) $node->name);
  17442. }
  17443. protected function resolveAttrGroups(Node $node): void
  17444. {
  17445. foreach ($node->attrGroups as $attrGroup) {
  17446. foreach ($attrGroup->attrs as $attr) {
  17447. $attr->name = $this->resolveClassName($attr->name);
  17448. }
  17449. }
  17450. }
  17451. }
  17452. <?php
  17453. declare (strict_types=1);
  17454. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17455. use PHPUnitPHAR\PhpParser\Node;
  17456. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17457. /**
  17458. * Visitor that connects a child node to its parent node
  17459. * as well as its sibling nodes.
  17460. *
  17461. * On the child node, the parent node can be accessed through
  17462. * <code>$node->getAttribute('parent')</code>, the previous
  17463. * node can be accessed through <code>$node->getAttribute('previous')</code>,
  17464. * and the next node can be accessed through <code>$node->getAttribute('next')</code>.
  17465. */
  17466. final class NodeConnectingVisitor extends NodeVisitorAbstract
  17467. {
  17468. /**
  17469. * @var Node[]
  17470. */
  17471. private array $stack = [];
  17472. /**
  17473. * @var ?Node
  17474. */
  17475. private $previous;
  17476. public function beforeTraverse(array $nodes)
  17477. {
  17478. $this->stack = [];
  17479. $this->previous = null;
  17480. }
  17481. public function enterNode(Node $node)
  17482. {
  17483. if (!empty($this->stack)) {
  17484. $node->setAttribute('parent', $this->stack[count($this->stack) - 1]);
  17485. }
  17486. if ($this->previous !== null && $this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
  17487. $node->setAttribute('previous', $this->previous);
  17488. $this->previous->setAttribute('next', $node);
  17489. }
  17490. $this->stack[] = $node;
  17491. }
  17492. public function leaveNode(Node $node)
  17493. {
  17494. $this->previous = $node;
  17495. array_pop($this->stack);
  17496. }
  17497. }
  17498. <?php
  17499. declare (strict_types=1);
  17500. namespace PHPUnitPHAR\PhpParser\NodeVisitor;
  17501. use PHPUnitPHAR\PhpParser\Node;
  17502. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  17503. use function array_pop;
  17504. use function count;
  17505. /**
  17506. * Visitor that connects a child node to its parent node.
  17507. *
  17508. * On the child node, the parent node can be accessed through
  17509. * <code>$node->getAttribute('parent')</code>.
  17510. */
  17511. final class ParentConnectingVisitor extends NodeVisitorAbstract
  17512. {
  17513. /**
  17514. * @var Node[]
  17515. */
  17516. private array $stack = [];
  17517. public function beforeTraverse(array $nodes)
  17518. {
  17519. $this->stack = [];
  17520. }
  17521. public function enterNode(Node $node)
  17522. {
  17523. if (!empty($this->stack)) {
  17524. $node->setAttribute('parent', $this->stack[count($this->stack) - 1]);
  17525. }
  17526. $this->stack[] = $node;
  17527. }
  17528. public function leaveNode(Node $node)
  17529. {
  17530. array_pop($this->stack);
  17531. }
  17532. }
  17533. <?php
  17534. declare (strict_types=1);
  17535. namespace PHPUnitPHAR\PhpParser;
  17536. /**
  17537. * @codeCoverageIgnore
  17538. */
  17539. abstract class NodeVisitorAbstract implements NodeVisitor
  17540. {
  17541. public function beforeTraverse(array $nodes)
  17542. {
  17543. return null;
  17544. }
  17545. public function enterNode(Node $node)
  17546. {
  17547. return null;
  17548. }
  17549. public function leaveNode(Node $node)
  17550. {
  17551. return null;
  17552. }
  17553. public function afterTraverse(array $nodes)
  17554. {
  17555. return null;
  17556. }
  17557. }
  17558. <?php
  17559. declare (strict_types=1);
  17560. namespace PHPUnitPHAR\PhpParser;
  17561. interface Parser
  17562. {
  17563. /**
  17564. * Parses PHP code into a node tree.
  17565. *
  17566. * @param string $code The source code to parse
  17567. * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
  17568. * to ErrorHandler\Throwing.
  17569. *
  17570. * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
  17571. * the parser was unable to recover from an error).
  17572. */
  17573. public function parse(string $code, ?ErrorHandler $errorHandler = null): ?array;
  17574. /**
  17575. * Return tokens for the last parse.
  17576. *
  17577. * @return Token[]
  17578. */
  17579. public function getTokens(): array;
  17580. }
  17581. <?php
  17582. declare (strict_types=1);
  17583. namespace PHPUnitPHAR\PhpParser\Parser;
  17584. use PHPUnitPHAR\PhpParser\Error;
  17585. use PHPUnitPHAR\PhpParser\Modifiers;
  17586. use PHPUnitPHAR\PhpParser\Node;
  17587. use PHPUnitPHAR\PhpParser\Node\Expr;
  17588. use PHPUnitPHAR\PhpParser\Node\Name;
  17589. use PHPUnitPHAR\PhpParser\Node\Scalar;
  17590. use PHPUnitPHAR\PhpParser\Node\Stmt;
  17591. /* This is an automatically GENERATED file, which should not be manually edited.
  17592. * Instead edit one of the following:
  17593. * * the grammar file grammar/php.y
  17594. * * the skeleton file grammar/parser.template
  17595. * * the preprocessing script grammar/rebuildParsers.php
  17596. */
  17597. class Php7 extends \PHPUnitPHAR\PhpParser\ParserAbstract
  17598. {
  17599. public const YYERRTOK = 256;
  17600. public const T_THROW = 257;
  17601. public const T_INCLUDE = 258;
  17602. public const T_INCLUDE_ONCE = 259;
  17603. public const T_EVAL = 260;
  17604. public const T_REQUIRE = 261;
  17605. public const T_REQUIRE_ONCE = 262;
  17606. public const T_LOGICAL_OR = 263;
  17607. public const T_LOGICAL_XOR = 264;
  17608. public const T_LOGICAL_AND = 265;
  17609. public const T_PRINT = 266;
  17610. public const T_YIELD = 267;
  17611. public const T_DOUBLE_ARROW = 268;
  17612. public const T_YIELD_FROM = 269;
  17613. public const T_PLUS_EQUAL = 270;
  17614. public const T_MINUS_EQUAL = 271;
  17615. public const T_MUL_EQUAL = 272;
  17616. public const T_DIV_EQUAL = 273;
  17617. public const T_CONCAT_EQUAL = 274;
  17618. public const T_MOD_EQUAL = 275;
  17619. public const T_AND_EQUAL = 276;
  17620. public const T_OR_EQUAL = 277;
  17621. public const T_XOR_EQUAL = 278;
  17622. public const T_SL_EQUAL = 279;
  17623. public const T_SR_EQUAL = 280;
  17624. public const T_POW_EQUAL = 281;
  17625. public const T_COALESCE_EQUAL = 282;
  17626. public const T_COALESCE = 283;
  17627. public const T_BOOLEAN_OR = 284;
  17628. public const T_BOOLEAN_AND = 285;
  17629. public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 286;
  17630. public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 287;
  17631. public const T_IS_EQUAL = 288;
  17632. public const T_IS_NOT_EQUAL = 289;
  17633. public const T_IS_IDENTICAL = 290;
  17634. public const T_IS_NOT_IDENTICAL = 291;
  17635. public const T_SPACESHIP = 292;
  17636. public const T_IS_SMALLER_OR_EQUAL = 293;
  17637. public const T_IS_GREATER_OR_EQUAL = 294;
  17638. public const T_SL = 295;
  17639. public const T_SR = 296;
  17640. public const T_INSTANCEOF = 297;
  17641. public const T_INC = 298;
  17642. public const T_DEC = 299;
  17643. public const T_INT_CAST = 300;
  17644. public const T_DOUBLE_CAST = 301;
  17645. public const T_STRING_CAST = 302;
  17646. public const T_ARRAY_CAST = 303;
  17647. public const T_OBJECT_CAST = 304;
  17648. public const T_BOOL_CAST = 305;
  17649. public const T_UNSET_CAST = 306;
  17650. public const T_POW = 307;
  17651. public const T_NEW = 308;
  17652. public const T_CLONE = 309;
  17653. public const T_EXIT = 310;
  17654. public const T_IF = 311;
  17655. public const T_ELSEIF = 312;
  17656. public const T_ELSE = 313;
  17657. public const T_ENDIF = 314;
  17658. public const T_LNUMBER = 315;
  17659. public const T_DNUMBER = 316;
  17660. public const T_STRING = 317;
  17661. public const T_STRING_VARNAME = 318;
  17662. public const T_VARIABLE = 319;
  17663. public const T_NUM_STRING = 320;
  17664. public const T_INLINE_HTML = 321;
  17665. public const T_ENCAPSED_AND_WHITESPACE = 322;
  17666. public const T_CONSTANT_ENCAPSED_STRING = 323;
  17667. public const T_ECHO = 324;
  17668. public const T_DO = 325;
  17669. public const T_WHILE = 326;
  17670. public const T_ENDWHILE = 327;
  17671. public const T_FOR = 328;
  17672. public const T_ENDFOR = 329;
  17673. public const T_FOREACH = 330;
  17674. public const T_ENDFOREACH = 331;
  17675. public const T_DECLARE = 332;
  17676. public const T_ENDDECLARE = 333;
  17677. public const T_AS = 334;
  17678. public const T_SWITCH = 335;
  17679. public const T_MATCH = 336;
  17680. public const T_ENDSWITCH = 337;
  17681. public const T_CASE = 338;
  17682. public const T_DEFAULT = 339;
  17683. public const T_BREAK = 340;
  17684. public const T_CONTINUE = 341;
  17685. public const T_GOTO = 342;
  17686. public const T_FUNCTION = 343;
  17687. public const T_FN = 344;
  17688. public const T_CONST = 345;
  17689. public const T_RETURN = 346;
  17690. public const T_TRY = 347;
  17691. public const T_CATCH = 348;
  17692. public const T_FINALLY = 349;
  17693. public const T_USE = 350;
  17694. public const T_INSTEADOF = 351;
  17695. public const T_GLOBAL = 352;
  17696. public const T_STATIC = 353;
  17697. public const T_ABSTRACT = 354;
  17698. public const T_FINAL = 355;
  17699. public const T_PRIVATE = 356;
  17700. public const T_PROTECTED = 357;
  17701. public const T_PUBLIC = 358;
  17702. public const T_READONLY = 359;
  17703. public const T_PUBLIC_SET = 360;
  17704. public const T_PROTECTED_SET = 361;
  17705. public const T_PRIVATE_SET = 362;
  17706. public const T_VAR = 363;
  17707. public const T_UNSET = 364;
  17708. public const T_ISSET = 365;
  17709. public const T_EMPTY = 366;
  17710. public const T_HALT_COMPILER = 367;
  17711. public const T_CLASS = 368;
  17712. public const T_TRAIT = 369;
  17713. public const T_INTERFACE = 370;
  17714. public const T_ENUM = 371;
  17715. public const T_EXTENDS = 372;
  17716. public const T_IMPLEMENTS = 373;
  17717. public const T_OBJECT_OPERATOR = 374;
  17718. public const T_NULLSAFE_OBJECT_OPERATOR = 375;
  17719. public const T_LIST = 376;
  17720. public const T_ARRAY = 377;
  17721. public const T_CALLABLE = 378;
  17722. public const T_CLASS_C = 379;
  17723. public const T_TRAIT_C = 380;
  17724. public const T_METHOD_C = 381;
  17725. public const T_FUNC_C = 382;
  17726. public const T_PROPERTY_C = 383;
  17727. public const T_LINE = 384;
  17728. public const T_FILE = 385;
  17729. public const T_START_HEREDOC = 386;
  17730. public const T_END_HEREDOC = 387;
  17731. public const T_DOLLAR_OPEN_CURLY_BRACES = 388;
  17732. public const T_CURLY_OPEN = 389;
  17733. public const T_PAAMAYIM_NEKUDOTAYIM = 390;
  17734. public const T_NAMESPACE = 391;
  17735. public const T_NS_C = 392;
  17736. public const T_DIR = 393;
  17737. public const T_NS_SEPARATOR = 394;
  17738. public const T_ELLIPSIS = 395;
  17739. public const T_NAME_FULLY_QUALIFIED = 396;
  17740. public const T_NAME_QUALIFIED = 397;
  17741. public const T_NAME_RELATIVE = 398;
  17742. public const T_ATTRIBUTE = 399;
  17743. protected int $tokenToSymbolMapSize = 400;
  17744. protected int $actionTableSize = 1286;
  17745. protected int $gotoTableSize = 646;
  17746. protected int $invalidSymbol = 172;
  17747. protected int $errorSymbol = 1;
  17748. protected int $defaultAction = -32766;
  17749. protected int $unexpectedTokenRule = 32767;
  17750. protected int $YY2TBLSTATE = 437;
  17751. protected int $numNonLeafStates = 742;
  17752. protected array $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_PUBLIC_SET", "T_PROTECTED_SET", "T_PRIVATE_SET", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_PROPERTY_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'");
  17753. protected array $tokenToSymbol = array(0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 56, 170, 172, 171, 55, 172, 172, 165, 166, 53, 50, 8, 51, 52, 54, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 31, 163, 44, 16, 46, 30, 68, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 70, 172, 164, 36, 172, 169, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 167, 35, 168, 58, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162);
  17754. protected array $action = array(128, 129, 130, 565, 131, 132, 944, 754, 755, 756, 133, 38, 838, 485, 561, 1365, -32766, -32766, -32766, 0, 829, 1122, 1123, 1124, 1118, 1117, 1116, 1125, 1119, 1120, 1121, -32766, -32766, -32766, -332, 748, 747, -32766, 840, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 24, -32766, 1034, -568, 757, 1122, 1123, 1124, 1118, 1117, 1116, 1125, 1119, 1120, 1121, 2, 381, 382, 265, 134, 384, 761, 762, 763, 764, 1111, 425, 426, 1300, 329, 36, 248, 26, 291, 818, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 794, 566, 795, 796, 797, 798, 786, 787, 346, 347, 789, 790, 775, 776, 777, 779, 780, 781, 357, 821, 822, 823, 824, 825, 567, -568, -568, 299, 782, 783, 568, 569, -194, 806, 804, 805, 817, 801, 802, 35, -193, 570, 571, 800, 572, 573, 574, 575, -32766, 576, 577, 471, 472, 486, 238, -568, 803, 578, 579, -371, 135, -371, 128, 129, 130, 565, 131, 132, 1067, 754, 755, 756, 133, 38, -32766, 136, 728, 1027, 1026, 1025, 1031, 1028, 1029, 1030, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 101, 102, 103, 104, 105, -332, 748, 747, 1043, 923, -32766, -32766, -32766, 839, -32766, 145, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 757, -32766, -32766, -32766, 611, -32766, 290, -32766, -32766, -32766, -32766, -32766, 834, 718, 265, 134, 384, 761, 762, 763, 764, -615, -32766, 426, -32766, -32766, -32766, -32766, -615, 251, 818, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 794, 566, 795, 796, 797, 798, 786, 787, 346, 347, 789, 790, 775, 776, 777, 779, 780, 781, 357, 821, 822, 823, 824, 825, 567, 913, 426, 310, 782, 783, 568, 569, -194, 806, 804, 805, 817, 801, 802, 1288, -193, 570, 571, 800, 572, 573, 574, 575, -273, 576, 577, 835, 82, 83, 84, -85, 803, 578, 579, 237, 148, 778, 749, 750, 751, 752, 753, 150, 754, 755, 756, 791, 792, 37, -32766, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 1043, 276, -32766, -32766, -32766, 925, 1263, 1262, 1264, 713, 831, 312, 393, 109, 7, 1097, 47, 757, -32766, -32766, -32766, 838, -85, -32766, 1095, -32766, -32766, -32766, 1268, -32766, -32766, 758, 759, 760, 761, 762, 763, 764, 994, -32766, 827, -32766, -32766, 923, -615, 324, -615, 818, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 794, 816, 795, 796, 797, 798, 786, 787, 788, 815, 789, 790, 775, 776, 777, 779, 780, 781, 820, 821, 822, 823, 824, 825, 826, 300, 301, 342, 782, 783, 784, 785, 833, 806, 804, 805, 817, 801, 802, 715, 1040, 793, 799, 800, 807, 808, 810, 809, 140, 811, 812, 838, 327, 343, -32766, 125, 803, 814, 813, 49, 50, 51, 517, 52, 53, 1043, -110, 371, 913, 54, 55, -110, 56, -110, -566, -32766, -32766, -32766, 306, 1043, 126, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -612, 1096, 106, 107, 108, 740, 276, -612, 963, 964, -32766, 290, 287, 965, 1330, 57, 58, -32766, 109, 375, 995, 59, 959, 60, 245, 246, 61, 62, 63, 64, 65, 66, 67, 68, -32766, 28, 267, 69, 441, 518, 391, -346, 74, 1294, 1295, 519, 443, 838, 327, -566, -566, 1292, 42, 20, 520, 925, 521, 923, 522, 713, 523, -564, 693, 524, 525, -566, 923, 444, 44, 45, 447, 378, 377, -78, 46, 526, 923, -572, 445, -566, 369, 341, 1346, 103, 104, 105, -563, 1254, 923, 383, 382, 446, 528, 529, 530, 865, 719, 866, 694, 425, 461, 462, 463, 844, 532, 533, 720, 1280, 1281, 1282, 1283, 1285, 1277, 1278, 298, 865, 151, 866, 723, 153, 1284, 1279, 695, 696, 1263, 1262, 1264, 299, -564, -564, 70, -153, -153, -153, 322, 323, 327, 154, -4, 923, 913, 1263, 1262, 1264, -564, 155, -153, 283, -153, 913, -153, 157, -153, -563, -563, 33, -571, 1350, -564, 913, -58, 829, 376, -612, 1349, -612, 748, 747, 837, -563, -606, 913, -606, 963, 964, -57, 748, 747, 527, 123, 81, -570, 1040, -563, 327, 617, 899, 959, -110, -110, -110, 32, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, -565, 1043, 947, 28, 268, 149, 408, 923, 1375, 829, 137, 1376, 138, 925, 144, 838, 913, 713, -153, 1292, 660, 21, 925, 679, 680, 283, 713, 158, 1170, 1172, 379, 380, 980, 385, 386, 159, 713, 730, 376, -562, 438, 1066, 141, 160, 925, 297, 327, 161, 713, 963, 964, 946, 651, 652, 527, 1254, -87, 162, -306, 748, 747, -84, 531, 959, -110, -110, -110, -565, -565, -78, 287, 1268, 532, 533, -73, 1280, 1281, 1282, 1283, 1285, 1277, 1278, -72, -565, -71, -70, 11, 1261, 1284, 1279, 913, -69, 748, 747, -68, 925, -32766, -565, 72, 713, -4, -16, 1261, 323, 327, -67, -562, -562, 291, -32766, -32766, -32766, -66, -32766, -65, -32766, -46, -32766, -18, 142, -32766, 275, -562, 1259, 284, -32766, -32766, -32766, 729, -32766, 732, -32766, -32766, 922, 147, 1261, -562, -32766, 422, 28, 267, -302, -32766, -32766, -32766, 279, -32766, 1042, -32766, -32766, -32766, 838, 838, -32766, 288, 1292, 1040, 280, -32766, -32766, -32766, 285, 286, 335, -32766, -32766, 1263, 1262, 1264, 925, -32766, 422, 289, 713, 28, 268, 292, 293, 276, 940, 73, 1043, -32766, 109, 689, 146, 838, -110, -110, -562, 1292, 1254, -110, 829, -32766, 1377, 704, 582, 10, 661, 838, -110, 1129, 706, 649, 283, 307, 960, -32766, 533, -32766, 1280, 1281, 1282, 1283, 1285, 1277, 1278, 682, 1043, 305, -50, 468, 1299, 1284, 1279, 1254, 666, -528, 496, 667, 304, 299, 683, 72, 74, 1301, 588, -32766, 323, 327, 327, -518, 290, 533, 40, 1280, 1281, 1282, 1283, 1285, 1277, 1278, 8, 139, 0, -562, -562, 27, 1284, 1279, -276, 407, 0, -32766, 0, 0, 0, 0, 72, 1261, 311, -562, 0, 323, 327, 0, -32766, -32766, -32766, 0, -32766, 373, -32766, 0, -32766, -562, 0, -32766, 0, 0, 615, 0, -32766, -32766, -32766, 923, -32766, 0, -32766, -32766, 942, 1289, 1261, 837, -32766, 422, 41, 299, 34, -32766, -32766, -32766, 737, -32766, 738, -32766, -32766, -32766, 923, 857, -32766, 904, 1004, 981, 988, -32766, -32766, -32766, 978, -32766, 989, -32766, -32766, 902, 976, 1261, 1100, -32766, 422, 48, 1103, 1104, -32766, -32766, -32766, 1101, -32766, 1102, -32766, -32766, -32766, 1108, -600, -32766, 849, 1316, 1334, 491, -32766, -32766, -32766, 1368, -32766, 654, -32766, -32766, -599, -598, 1261, 595, -32766, 422, -572, -571, 1268, -32766, -32766, -32766, 913, -32766, -570, -32766, -32766, -32766, -569, -512, -32766, -274, 1, 29, 30, -32766, -32766, -32766, -251, -251, -251, -32766, -32766, 39, 376, 913, 43, -32766, 422, 71, 302, 303, 75, 76, 77, 963, 964, 78, 79, -32766, 527, -250, -250, -250, -273, 80, 374, 376, 899, 959, -110, -110, -110, 143, 152, 156, 243, 331, 963, 964, 127, 358, 359, 527, 360, 361, 362, 363, 364, 365, 366, 899, 959, -110, -110, -110, -32766, 13, 367, 838, 368, 925, 1261, 14, 370, 713, -251, 439, 560, -32766, -32766, -32766, 15, -32766, 16, -32766, 18, -32766, 406, 487, -32766, 488, 495, 498, 925, -32766, -32766, -32766, 713, -250, 499, -32766, -32766, 500, -110, -110, 501, -32766, 422, -110, 505, 506, 507, 515, 593, 699, 1069, 1210, -110, -32766, 1290, 1068, 1049, 1249, 1045, -278, -102, -32766, 12, 17, 22, 296, 405, 607, 612, 640, 705, 1214, 1267, 1211, 1347, 0, 321, 372, 714, 717, 721, 722, 724, 299, 725, 726, 74, 727, 1227, 731, 716, 0, 327, 411, 1293, 734, 900, 1372, 1374, 860, 859, 953, 996, 1373, 952, 950, 951, 954, 1242, 933, 943, 931, 986, 987, 638, 1371, 1328, 1317, 1335, 1344, 0, 0, 0, 327);
  17755. protected array $actionCheck = array(2, 3, 4, 5, 6, 7, 1, 9, 10, 11, 12, 13, 82, 31, 85, 85, 9, 10, 11, 0, 80, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 9, 10, 11, 8, 37, 38, 30, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 101, 30, 1, 70, 57, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 8, 106, 107, 71, 72, 73, 74, 75, 76, 77, 126, 116, 80, 150, 70, 151, 152, 8, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 137, 138, 162, 126, 127, 128, 129, 8, 131, 132, 133, 134, 135, 136, 8, 8, 139, 140, 141, 142, 143, 144, 145, 9, 147, 148, 137, 138, 167, 14, 167, 154, 155, 156, 106, 158, 108, 2, 3, 4, 5, 6, 7, 166, 9, 10, 11, 12, 13, 116, 8, 167, 119, 120, 121, 122, 123, 124, 125, 9, 10, 11, 44, 45, 46, 47, 48, 49, 50, 51, 52, 166, 37, 38, 141, 1, 9, 10, 11, 163, 30, 8, 32, 33, 34, 35, 36, 37, 38, 9, 10, 11, 57, 9, 10, 11, 1, 30, 165, 32, 33, 34, 35, 36, 80, 31, 71, 72, 73, 74, 75, 76, 77, 1, 30, 80, 32, 33, 34, 35, 8, 8, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 84, 80, 8, 126, 127, 128, 129, 166, 131, 132, 133, 134, 135, 136, 1, 166, 139, 140, 141, 142, 143, 144, 145, 166, 147, 148, 160, 9, 10, 11, 31, 154, 155, 156, 97, 158, 2, 3, 4, 5, 6, 7, 14, 9, 10, 11, 12, 13, 30, 116, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 141, 57, 9, 10, 11, 163, 159, 160, 161, 167, 80, 8, 106, 69, 108, 168, 70, 57, 9, 10, 11, 82, 97, 30, 1, 32, 33, 34, 1, 9, 10, 71, 72, 73, 74, 75, 76, 77, 31, 30, 80, 32, 33, 1, 164, 8, 166, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 137, 138, 8, 126, 127, 128, 129, 160, 131, 132, 133, 134, 135, 136, 167, 116, 139, 140, 141, 142, 143, 144, 145, 167, 147, 148, 82, 171, 8, 116, 167, 154, 155, 156, 2, 3, 4, 5, 6, 7, 141, 101, 8, 84, 12, 13, 106, 15, 108, 70, 9, 10, 11, 113, 141, 14, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 1, 163, 53, 54, 55, 167, 57, 8, 117, 118, 116, 165, 30, 122, 1, 50, 51, 140, 69, 8, 163, 56, 131, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 140, 70, 71, 72, 73, 74, 8, 168, 165, 78, 79, 80, 8, 82, 171, 137, 138, 86, 87, 88, 89, 163, 91, 1, 93, 167, 95, 70, 80, 98, 99, 153, 1, 8, 103, 104, 105, 106, 107, 16, 109, 110, 1, 165, 8, 167, 115, 116, 1, 50, 51, 52, 70, 122, 1, 106, 107, 8, 127, 128, 129, 106, 31, 108, 116, 116, 132, 133, 134, 8, 139, 140, 31, 142, 143, 144, 145, 146, 147, 148, 149, 106, 14, 108, 31, 14, 155, 156, 140, 141, 159, 160, 161, 162, 137, 138, 165, 75, 76, 77, 169, 170, 171, 14, 0, 1, 84, 159, 160, 161, 153, 14, 90, 165, 92, 84, 94, 14, 96, 137, 138, 14, 165, 1, 167, 84, 16, 80, 106, 164, 8, 166, 37, 38, 159, 153, 164, 84, 166, 117, 118, 16, 37, 38, 122, 16, 167, 165, 116, 167, 171, 51, 130, 131, 132, 133, 134, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 70, 141, 73, 70, 71, 101, 102, 1, 80, 80, 16, 83, 16, 163, 16, 82, 84, 167, 168, 86, 75, 76, 163, 75, 76, 165, 167, 16, 59, 60, 106, 107, 163, 106, 107, 16, 167, 31, 106, 70, 108, 1, 167, 16, 163, 113, 171, 16, 167, 117, 118, 122, 111, 112, 122, 122, 31, 16, 35, 37, 38, 31, 130, 131, 132, 133, 134, 137, 138, 31, 30, 1, 139, 140, 31, 142, 143, 144, 145, 146, 147, 148, 31, 153, 31, 31, 154, 80, 155, 156, 84, 31, 37, 38, 31, 163, 74, 167, 165, 167, 168, 31, 80, 170, 171, 31, 137, 138, 30, 87, 88, 89, 31, 91, 31, 93, 31, 95, 31, 31, 98, 31, 153, 116, 31, 103, 104, 105, 31, 74, 31, 109, 110, 31, 31, 80, 167, 115, 116, 70, 71, 35, 87, 88, 89, 35, 91, 140, 93, 127, 95, 82, 82, 98, 37, 86, 116, 35, 103, 104, 105, 35, 35, 35, 109, 110, 159, 160, 161, 163, 115, 116, 37, 167, 70, 71, 37, 37, 57, 38, 158, 141, 127, 69, 77, 70, 82, 117, 118, 70, 86, 122, 122, 80, 116, 83, 80, 89, 97, 90, 82, 131, 82, 92, 113, 165, 114, 131, 85, 140, 140, 142, 143, 144, 145, 146, 147, 148, 94, 141, 136, 31, 97, 150, 155, 156, 122, 96, 153, 97, 100, 135, 162, 100, 165, 165, 150, 157, 140, 170, 171, 171, 153, 165, 140, 163, 142, 143, 144, 145, 146, 147, 148, 153, 31, -1, 137, 138, 153, 155, 156, 166, 168, -1, 74, -1, -1, -1, -1, 165, 80, 135, 153, -1, 170, 171, -1, 87, 88, 89, -1, 91, 153, 93, -1, 95, 167, -1, 98, -1, -1, 157, -1, 103, 104, 105, 1, 74, -1, 109, 110, 158, 164, 80, 159, 115, 116, 163, 162, 167, 87, 88, 89, 163, 91, 163, 93, 127, 95, 1, 163, 98, 163, 163, 163, 163, 103, 104, 105, 163, 74, 163, 109, 110, 163, 163, 80, 163, 115, 116, 70, 163, 163, 87, 88, 89, 163, 91, 163, 93, 127, 95, 163, 165, 98, 164, 164, 164, 102, 103, 104, 105, 164, 74, 164, 109, 110, 165, 165, 80, 81, 115, 116, 165, 165, 1, 87, 88, 89, 84, 91, 165, 93, 127, 95, 165, 165, 98, 166, 165, 165, 165, 103, 104, 105, 100, 101, 102, 109, 110, 165, 106, 84, 165, 115, 116, 165, 137, 138, 165, 165, 165, 117, 118, 165, 165, 127, 122, 100, 101, 102, 166, 165, 153, 106, 130, 131, 132, 133, 134, 165, 165, 165, 165, 165, 117, 118, 167, 165, 165, 122, 165, 165, 165, 165, 165, 165, 165, 130, 131, 132, 133, 134, 74, 166, 165, 82, 165, 163, 80, 166, 165, 167, 168, 165, 165, 87, 88, 89, 166, 91, 166, 93, 166, 95, 166, 166, 98, 166, 166, 166, 163, 103, 104, 105, 167, 168, 166, 109, 110, 166, 117, 118, 166, 115, 116, 122, 166, 166, 166, 166, 166, 166, 166, 166, 131, 127, 166, 166, 166, 166, 166, 166, 166, 140, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -1, 167, 167, 167, 167, 167, 167, 167, 162, 167, 167, 165, 167, 169, 167, 167, -1, 171, 168, 170, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -1, -1, -1, 171);
  17756. protected array $actionBase = array(0, -2, 156, 559, 641, 1004, 1027, 485, 292, 200, -60, 283, 568, 590, 590, 715, 590, 195, 578, 894, 395, 395, 395, 825, 313, 313, 825, 313, 731, 731, 731, 731, 764, 764, 965, 965, 998, 932, 899, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 37, 360, 216, 644, 1061, 1067, 1063, 1068, 1059, 1058, 1062, 1064, 1069, 1109, 1110, 812, 1111, 1112, 1108, 1113, 1065, 909, 1060, 1066, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 135, 477, 373, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 642, 642, 22, 22, 22, 362, 813, 778, 813, 813, 813, 813, 813, 813, 813, 813, 346, 205, 678, 188, 171, 171, 7, 7, 7, 7, 7, 376, 779, 54, 1083, 1083, 139, 139, 139, 139, -50, 49, 749, 380, 787, -39, 569, 569, 536, 536, 335, 335, 349, 349, 335, 335, 335, 212, 212, 212, 212, 415, 494, 519, 512, -71, 807, 584, 584, 584, 584, 807, 807, 807, 807, 795, 1086, 807, 807, 807, 639, 828, 828, 979, 452, 452, 452, 828, 492, -70, -70, 492, 394, -70, 516, 982, 637, 988, 397, 785, 486, 509, 397, -16, 299, 502, 233, 854, 633, 854, 1056, 832, 832, 794, 752, 898, 1085, 1070, 839, 1106, 842, 1107, 471, 10, 747, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1114, 632, 1056, 145, 1114, 1114, 1114, 632, 632, 632, 632, 632, 632, 632, 632, 796, 632, 632, 650, 145, 654, 657, 145, 837, 632, 798, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -18, 37, 37, 360, 5, 5, 37, 341, 52, 5, 5, 5, 5, 37, 37, 37, 37, 633, 830, 789, 636, 278, 843, 128, 830, 830, 830, 26, 136, 120, 732, 815, 259, 822, 822, 829, 933, 933, 822, 827, 822, 829, 822, 822, 933, 933, 855, 933, 163, 541, 430, 514, 562, 933, 273, 822, 822, 822, 822, 845, 933, 58, 573, 822, 234, 194, 822, 822, 845, 805, 802, 793, 933, 933, 933, 845, 470, 793, 793, 793, 859, 861, 800, 799, 390, 356, 598, 127, 850, 799, 799, 822, 535, 800, 799, 800, 799, 852, 799, 799, 799, 800, 799, 827, 456, 799, 720, 728, 586, 75, 799, 19, 950, 953, 734, 954, 944, 955, 1008, 958, 959, 1073, 930, 977, 947, 966, 1009, 935, 934, 811, 666, 692, 809, 784, 929, 823, 823, 823, 917, 918, 823, 823, 823, 823, 823, 823, 823, 823, 666, 847, 838, 817, 983, 703, 705, 1044, 782, 1090, 1081, 982, 950, 959, 739, 947, 966, 935, 934, 792, 790, 772, 783, 769, 763, 760, 762, 797, 1046, 974, 791, 707, 1016, 985, 1089, 1071, 986, 987, 1018, 1047, 866, 1050, 1091, 824, 1092, 1093, 900, 989, 1074, 823, 912, 897, 901, 988, 925, 666, 902, 1051, 997, 851, 1019, 1021, 1072, 834, 821, 907, 1094, 990, 991, 999, 1075, 1076, 853, 1003, 804, 1022, 841, 803, 1023, 1030, 1033, 1036, 1077, 1095, 1079, 911, 1080, 868, 818, 931, 840, 1096, 307, 835, 836, 849, 1005, 605, 978, 1082, 1087, 1097, 1040, 1041, 1042, 1098, 1099, 975, 869, 1012, 833, 1014, 964, 870, 871, 608, 848, 1052, 819, 831, 844, 626, 634, 1100, 1101, 1102, 976, 806, 816, 875, 877, 1053, 826, 1054, 1103, 640, 880, 1104, 1045, 736, 740, 560, 662, 647, 750, 820, 1084, 814, 801, 810, 1001, 740, 808, 881, 1105, 883, 887, 888, 1043, 892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, 468, 468, 468, 468, 468, 313, 313, 313, 313, 313, 468, 468, 468, 468, 468, 468, 468, 313, 468, 468, 468, 313, 0, 0, 313, 0, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 716, 716, 297, 297, 297, 297, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 297, 297, 0, 297, 297, 297, 297, 297, 297, 297, 297, 855, 716, 716, 716, 716, 452, 452, 452, 452, -95, -95, 716, 716, 716, 394, 716, 716, 452, 452, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 716, 0, 0, 0, 145, -70, 716, 827, 827, 827, 827, 716, 716, 716, 716, -70, -70, 716, 716, 716, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 145, 0, 0, 827, 638, 827, 638, 716, 394, 855, 659, 716, 0, 0, 0, 0, 145, 827, 145, 632, -70, -70, 632, 632, 5, 37, 659, 613, 613, 613, 613, 0, 0, 633, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 827, 0, 855, 0, 827, 827, 827, 0, 0, 0, 0, 0, 0, 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, 827, 0, 933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 823, 834, 0, 0, 834, 0, 823, 823, 823, 0, 0, 0, 848, 826);
  17757. protected array $actionDefault = array(3, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 618, 618, 618, 618, 32767, 32767, 255, 102, 32767, 32767, 487, 404, 404, 404, 32767, 32767, 560, 560, 560, 560, 560, 32767, 32767, 32767, 32767, 32767, 32767, 487, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 36, 7, 8, 10, 11, 49, 17, 328, 100, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 611, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 392, 491, 470, 471, 473, 474, 403, 561, 617, 331, 614, 333, 402, 145, 343, 334, 243, 259, 492, 260, 493, 496, 497, 216, 389, 149, 150, 434, 488, 436, 486, 490, 435, 409, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 407, 408, 489, 32767, 32767, 467, 466, 465, 432, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 433, 437, 406, 440, 438, 439, 456, 457, 454, 455, 458, 32767, 32767, 320, 32767, 32767, 459, 460, 461, 462, 370, 368, 32767, 32767, 320, 111, 32767, 32767, 447, 448, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 504, 554, 464, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 100, 556, 429, 431, 524, 442, 443, 441, 410, 32767, 529, 32767, 102, 32767, 531, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 555, 32767, 562, 562, 32767, 517, 100, 195, 32767, 530, 195, 195, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 625, 517, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 195, 110, 32767, 32767, 32767, 100, 195, 195, 195, 195, 195, 195, 195, 195, 532, 195, 195, 190, 32767, 269, 271, 102, 579, 195, 534, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 517, 452, 138, 32767, 519, 138, 562, 444, 445, 446, 562, 562, 562, 316, 293, 32767, 32767, 32767, 32767, 532, 532, 100, 100, 100, 100, 32767, 32767, 32767, 32767, 111, 503, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 224, 32767, 101, 99, 32767, 101, 101, 32767, 32767, 224, 226, 213, 228, 32767, 583, 584, 224, 101, 228, 228, 228, 248, 248, 506, 322, 101, 99, 101, 101, 197, 322, 322, 32767, 101, 506, 322, 506, 322, 199, 322, 322, 322, 506, 322, 32767, 101, 322, 215, 392, 99, 99, 322, 32767, 32767, 32767, 519, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 223, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 549, 32767, 567, 581, 450, 451, 453, 566, 564, 475, 476, 477, 478, 479, 480, 481, 483, 613, 32767, 523, 32767, 32767, 32767, 342, 32767, 623, 32767, 32767, 32767, 9, 74, 512, 42, 43, 51, 57, 538, 539, 540, 541, 535, 536, 542, 537, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 624, 32767, 562, 32767, 32767, 32767, 32767, 449, 544, 589, 32767, 32767, 563, 616, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 138, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 549, 32767, 136, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 545, 32767, 32767, 32767, 562, 32767, 32767, 32767, 32767, 318, 315, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 562, 32767, 32767, 32767, 32767, 32767, 295, 32767, 312, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 388, 519, 298, 300, 301, 32767, 32767, 32767, 32767, 364, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 345, 152, 152, 152, 345, 345, 152, 345, 345, 345, 152, 152, 152, 152, 152, 152, 281, 185, 263, 266, 248, 248, 152, 356, 152);
  17758. protected array $goto = array(196, 196, 1041, 352, 700, 465, 587, 470, 470, 1072, 736, 641, 643, 1205, 855, 663, 470, 856, 709, 687, 690, 1014, 698, 707, 1010, 625, 662, 166, 166, 166, 166, 220, 197, 193, 193, 176, 178, 215, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 188, 189, 190, 191, 192, 217, 215, 218, 540, 541, 423, 542, 545, 546, 547, 548, 549, 550, 551, 552, 1156, 167, 168, 169, 195, 170, 171, 172, 165, 173, 174, 175, 177, 214, 216, 219, 239, 242, 253, 254, 256, 257, 258, 259, 260, 261, 262, 263, 269, 270, 271, 272, 281, 282, 317, 318, 319, 429, 430, 431, 602, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 179, 236, 180, 188, 189, 190, 191, 192, 217, 1156, 198, 199, 200, 201, 240, 181, 182, 202, 183, 203, 199, 184, 241, 198, 164, 204, 205, 185, 206, 207, 208, 186, 209, 210, 187, 211, 212, 213, 278, 278, 278, 278, 858, 433, 665, 979, 916, 604, 917, 428, 320, 314, 315, 338, 597, 432, 339, 434, 642, 627, 627, 896, 854, 896, 896, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 614, 628, 631, 632, 633, 634, 655, 656, 657, 711, 830, 871, 460, 912, 907, 908, 921, 864, 909, 861, 910, 911, 862, 356, 915, 868, 421, 883, 482, 867, 870, 1361, 1361, 356, 356, 484, 1094, 1089, 1090, 1091, 889, 603, 1107, 397, 400, 605, 609, 356, 356, 1361, 594, 356, 712, 344, 1378, 353, 354, 511, 703, 442, 1105, 1260, 1041, 1260, 1260, 350, 559, 1364, 1364, 356, 356, 1041, 1260, 1041, 1351, 1041, 1041, 345, 344, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1000, 1236, 948, 249, 249, 1260, 1237, 1240, 949, 1241, 1260, 1260, 1260, 1260, 1114, 1115, 1260, 1260, 1260, 1343, 1343, 1343, 1343, 564, 557, 851, 427, 1322, 616, 395, 247, 247, 247, 247, 244, 250, 592, 929, 503, 664, 504, 930, 355, 355, 355, 355, 510, 945, 512, 945, 479, 1336, 1337, 328, 557, 564, 589, 590, 330, 600, 606, 1153, 621, 622, 555, 1065, 555, 555, 658, 659, 25, 676, 677, 678, 440, 555, 1310, 1310, 686, 559, 851, 670, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1044, 1044, 1047, 1046, 685, 956, 458, 340, 1036, 1052, 1053, 973, 973, 973, 973, 1050, 1051, 458, 967, 974, 1307, 1307, 971, 412, 708, 848, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 5, 610, 6, 873, 934, 1143, 451, 451, 876, 451, 451, 1333, 962, 1333, 1333, 1253, 1019, 404, 553, 553, 553, 553, 1333, 608, 875, 620, 668, 998, 1251, 558, 584, 1022, 869, 739, 558, 885, 584, 480, 398, 464, 1078, 697, 326, 309, 1250, 832, 1345, 1345, 1345, 1345, 1082, 473, 601, 474, 475, 1338, 1339, 697, 1128, 881, 697, 984, 1369, 1370, 598, 619, 1032, 0, 544, 544, 851, 836, 0, 1329, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 543, 543, 1255, 879, 0, 0, 543, 0, 543, 543, 543, 543, 543, 543, 543, 543, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 252, 252, 451, 836, 1080, 836, 409, 410, 1331, 1331, 1080, 674, 0, 675, 0, 414, 415, 416, 0, 688, 0, 0, 417, 635, 637, 639, 0, 348, 0, 0, 1256, 1257, 0, 1243, 884, 872, 1077, 1081, 0, 846, 1003, 0, 0, 975, 0, 735, 1243, 982, 556, 1012, 1007, 0, 435, 0, 0, 0, 0, 0, 1258, 1319, 1320, 0, 0, 435, 273, 325, 0, 325, 325, 0, 972, 1048, 1048, 0, 0, 0, 669, 1059, 1055, 1056, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1126, 888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 1017);
  17759. protected array $gotoCheck = array(42, 42, 73, 97, 73, 156, 48, 154, 154, 128, 48, 48, 48, 156, 26, 48, 154, 27, 9, 48, 48, 48, 48, 48, 48, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 23, 23, 23, 23, 15, 66, 66, 49, 65, 131, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 108, 108, 25, 25, 25, 25, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 6, 35, 83, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 43, 35, 84, 15, 35, 188, 188, 14, 14, 84, 15, 15, 15, 15, 45, 8, 8, 59, 59, 59, 59, 14, 14, 188, 178, 14, 8, 174, 14, 97, 97, 8, 8, 83, 8, 73, 73, 73, 73, 185, 14, 188, 188, 14, 14, 73, 73, 73, 187, 73, 73, 174, 174, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 103, 79, 79, 5, 5, 73, 79, 79, 79, 79, 73, 73, 73, 73, 145, 145, 73, 73, 73, 9, 9, 9, 9, 76, 76, 22, 13, 14, 13, 62, 5, 5, 5, 5, 5, 5, 104, 73, 160, 64, 160, 73, 24, 24, 24, 24, 160, 9, 14, 9, 182, 182, 182, 76, 76, 76, 76, 76, 76, 76, 76, 155, 76, 76, 19, 115, 19, 19, 86, 86, 76, 86, 86, 86, 113, 19, 176, 176, 117, 14, 22, 121, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 89, 89, 119, 119, 89, 89, 19, 29, 89, 89, 89, 19, 19, 19, 19, 120, 120, 19, 19, 19, 177, 177, 93, 93, 93, 18, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 46, 17, 46, 37, 17, 17, 23, 23, 39, 23, 23, 131, 92, 131, 131, 14, 17, 28, 107, 107, 107, 107, 131, 107, 17, 80, 17, 17, 166, 9, 9, 110, 17, 99, 9, 41, 9, 157, 9, 9, 130, 7, 175, 175, 17, 7, 131, 131, 131, 131, 133, 9, 9, 9, 9, 184, 184, 7, 148, 9, 7, 96, 9, 9, 2, 2, 114, -1, 179, 179, 22, 12, -1, 131, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 162, 162, 20, 9, -1, -1, 162, -1, 162, 162, 162, 162, 162, 162, 162, 162, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 5, 5, 23, 12, 131, 12, 82, 82, 131, 131, 131, 82, -1, 82, -1, 82, 82, 82, -1, 82, -1, -1, 82, 85, 85, 85, -1, 82, -1, -1, 20, 20, -1, 20, 16, 16, 16, 16, -1, 20, 50, -1, -1, 50, -1, 50, 20, 16, 50, 50, 50, -1, 118, -1, -1, -1, -1, -1, 20, 20, 20, -1, -1, 118, 24, 24, -1, 24, 24, -1, 16, 118, 118, -1, -1, -1, 118, 118, 118, 118, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 107, 107);
  17760. protected array $gotoBase = array(0, 0, -234, 0, 0, 291, 199, 451, 232, 8, 0, 0, 191, -25, -76, -183, 108, -48, 96, 88, 109, 0, 36, 159, 328, 182, 10, 13, 94, 91, 0, 0, 0, 0, 0, -162, 0, 78, 0, 101, 0, 9, -1, 202, 0, 213, -322, 0, -708, 151, 556, 0, 0, 0, 0, 0, -15, 0, 0, 197, 0, 0, 276, 0, 90, 156, -70, 0, 0, 0, 0, 0, 0, -5, 0, 0, -34, 0, 0, -119, 112, -160, 40, -67, -246, 69, -364, 0, 0, 102, 0, 0, 97, 98, 0, 0, 33, -483, 0, 42, 0, 0, 0, 254, 282, 0, 0, 407, -54, 0, 77, 0, 0, 86, -29, 79, 0, 84, 314, 104, 111, 80, 0, 0, 0, 0, 0, 0, 7, 0, 82, 163, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 29, 0, 0, 0, 0, 0, -27, 106, -263, 12, 0, 0, -171, 0, 264, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, -46, 137, 128, 164, 220, 248, 0, 0, 38, 0, 99, 234, 0, 242, -78, 0, 0);
  17761. protected array $gotoDefault = array(-32768, 516, 743, 4, 744, 938, 819, 828, 580, 534, 710, 349, 629, 424, 1327, 914, 1142, 599, 847, 1269, 1275, 459, 850, 333, 733, 926, 897, 898, 401, 388, 863, 399, 653, 630, 497, 882, 455, 874, 489, 877, 454, 886, 163, 420, 514, 890, 3, 893, 562, 924, 977, 389, 901, 390, 681, 903, 583, 905, 906, 396, 402, 403, 1147, 591, 626, 918, 255, 585, 919, 387, 920, 928, 392, 394, 691, 469, 508, 502, 413, 1109, 586, 613, 650, 448, 476, 624, 636, 623, 483, 436, 418, 332, 961, 969, 490, 467, 983, 351, 991, 741, 1155, 644, 492, 999, 645, 1006, 1009, 535, 536, 481, 1021, 266, 1024, 493, 1033, 23, 671, 1038, 1039, 672, 646, 1061, 647, 673, 648, 1063, 466, 581, 1071, 456, 1079, 1315, 457, 1083, 264, 1086, 277, 419, 437, 1092, 1093, 9, 1099, 701, 702, 19, 274, 513, 1127, 692, -32768, -32768, -32768, -32768, 453, 1154, 452, 1224, 1226, 563, 494, 1244, 294, 1247, 684, 509, 1252, 449, 1318, 450, 537, 477, 316, 538, 1362, 308, 336, 313, 554, 295, 337, 539, 478, 1324, 1332, 334, 31, 1352, 1363, 596, 618);
  17762. protected array $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 80, 26, 26, 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, 81, 109, 109, 111, 111, 112, 112, 112, 112, 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, 20, 127, 126, 126, 128, 128, 128, 128, 60, 129, 129, 130, 61, 132, 132, 133, 133, 134, 134, 86, 135, 135, 135, 135, 135, 135, 135, 140, 140, 141, 141, 142, 142, 142, 142, 142, 143, 144, 144, 139, 139, 136, 136, 138, 138, 146, 146, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 137, 147, 147, 149, 148, 148, 150, 150, 114, 151, 151, 153, 153, 153, 152, 152, 62, 104, 154, 154, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 161, 162, 162, 163, 155, 155, 160, 160, 164, 165, 165, 166, 167, 168, 168, 168, 168, 19, 19, 73, 73, 73, 73, 156, 156, 156, 156, 170, 170, 159, 159, 159, 157, 157, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, 177, 108, 179, 179, 179, 179, 158, 158, 158, 158, 158, 158, 158, 158, 59, 59, 173, 173, 173, 173, 173, 180, 180, 169, 169, 169, 169, 181, 181, 181, 181, 181, 181, 74, 74, 66, 66, 66, 66, 131, 131, 131, 131, 184, 183, 172, 172, 172, 172, 172, 172, 172, 171, 171, 171, 182, 182, 182, 182, 107, 178, 186, 186, 185, 185, 187, 187, 187, 187, 187, 187, 187, 187, 175, 175, 175, 175, 174, 189, 188, 188, 188, 188, 188, 188, 188, 188, 190, 190, 190, 190);
  17763. protected array $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, 4, 1, 3, 1, 1, 8, 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 1, 1, 1, 7, 9, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, 6, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 0, 2, 0, 5, 8, 1, 3, 3, 0, 2, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 2, 1, 1, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1);
  17764. protected function initReduceCallbacks(): void
  17765. {
  17766. $this->reduceCallbacks = [0 => null, 1 => static function ($self, $stackPos) {
  17767. $self->semValue = $self->handleNamespaces($self->semStack[$stackPos - (1 - 1)]);
  17768. }, 2 => static function ($self, $stackPos) {
  17769. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  17770. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  17771. }
  17772. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  17773. }, 3 => static function ($self, $stackPos) {
  17774. $self->semValue = array();
  17775. }, 4 => static function ($self, $stackPos) {
  17776. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  17777. if ($nop !== null) {
  17778. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  17779. }
  17780. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  17781. }, 5 => null, 6 => null, 7 => null, 8 => null, 9 => null, 10 => null, 11 => null, 12 => null, 13 => null, 14 => null, 15 => null, 16 => null, 17 => null, 18 => null, 19 => null, 20 => null, 21 => null, 22 => null, 23 => null, 24 => null, 25 => null, 26 => null, 27 => null, 28 => null, 29 => null, 30 => null, 31 => null, 32 => null, 33 => null, 34 => null, 35 => null, 36 => null, 37 => null, 38 => null, 39 => null, 40 => null, 41 => null, 42 => null, 43 => null, 44 => null, 45 => null, 46 => null, 47 => null, 48 => null, 49 => null, 50 => null, 51 => null, 52 => null, 53 => null, 54 => null, 55 => null, 56 => null, 57 => null, 58 => null, 59 => null, 60 => null, 61 => null, 62 => null, 63 => null, 64 => null, 65 => null, 66 => null, 67 => null, 68 => null, 69 => null, 70 => null, 71 => null, 72 => null, 73 => null, 74 => null, 75 => null, 76 => static function ($self, $stackPos) {
  17782. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  17783. if ($self->semValue === "<?=") {
  17784. $self->emitError(new Error('Cannot use "<?=" as an identifier', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
  17785. }
  17786. }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => static function ($self, $stackPos) {
  17787. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17788. }, 86 => static function ($self, $stackPos) {
  17789. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17790. }, 87 => static function ($self, $stackPos) {
  17791. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17792. }, 88 => static function ($self, $stackPos) {
  17793. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17794. }, 89 => static function ($self, $stackPos) {
  17795. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17796. }, 90 => static function ($self, $stackPos) {
  17797. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17798. }, 91 => static function ($self, $stackPos) {
  17799. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17800. }, 92 => static function ($self, $stackPos) {
  17801. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17802. }, 93 => static function ($self, $stackPos) {
  17803. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17804. }, 94 => null, 95 => static function ($self, $stackPos) {
  17805. $self->semValue = new Name(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17806. }, 96 => static function ($self, $stackPos) {
  17807. $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17808. }, 97 => static function ($self, $stackPos) {
  17809. /* nothing */
  17810. }, 98 => static function ($self, $stackPos) {
  17811. /* nothing */
  17812. }, 99 => static function ($self, $stackPos) {
  17813. /* nothing */
  17814. }, 100 => static function ($self, $stackPos) {
  17815. $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
  17816. }, 101 => null, 102 => null, 103 => static function ($self, $stackPos) {
  17817. $self->semValue = new Node\Attribute($self->semStack[$stackPos - (1 - 1)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17818. }, 104 => static function ($self, $stackPos) {
  17819. $self->semValue = new Node\Attribute($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  17820. }, 105 => static function ($self, $stackPos) {
  17821. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17822. }, 106 => static function ($self, $stackPos) {
  17823. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17824. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17825. }, 107 => static function ($self, $stackPos) {
  17826. $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  17827. }, 108 => static function ($self, $stackPos) {
  17828. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17829. }, 109 => static function ($self, $stackPos) {
  17830. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  17831. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  17832. }, 110 => static function ($self, $stackPos) {
  17833. $self->semValue = [];
  17834. }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => static function ($self, $stackPos) {
  17835. $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  17836. }, 116 => static function ($self, $stackPos) {
  17837. $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (3 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17838. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
  17839. $self->checkNamespace($self->semValue);
  17840. }, 117 => static function ($self, $stackPos) {
  17841. $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  17842. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
  17843. $self->checkNamespace($self->semValue);
  17844. }, 118 => static function ($self, $stackPos) {
  17845. $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  17846. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
  17847. $self->checkNamespace($self->semValue);
  17848. }, 119 => static function ($self, $stackPos) {
  17849. $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17850. }, 120 => static function ($self, $stackPos) {
  17851. $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  17852. }, 121 => null, 122 => static function ($self, $stackPos) {
  17853. $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17854. }, 123 => static function ($self, $stackPos) {
  17855. $self->semValue = Stmt\Use_::TYPE_FUNCTION;
  17856. }, 124 => static function ($self, $stackPos) {
  17857. $self->semValue = Stmt\Use_::TYPE_CONSTANT;
  17858. }, 125 => static function ($self, $stackPos) {
  17859. $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 6)], $self->semStack[$stackPos - (8 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  17860. }, 126 => static function ($self, $stackPos) {
  17861. $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  17862. }, 127 => null, 128 => static function ($self, $stackPos) {
  17863. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17864. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17865. }, 129 => static function ($self, $stackPos) {
  17866. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17867. }, 130 => null, 131 => static function ($self, $stackPos) {
  17868. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17869. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17870. }, 132 => static function ($self, $stackPos) {
  17871. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17872. }, 133 => null, 134 => static function ($self, $stackPos) {
  17873. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17874. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17875. }, 135 => static function ($self, $stackPos) {
  17876. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17877. }, 136 => static function ($self, $stackPos) {
  17878. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17879. $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
  17880. }, 137 => static function ($self, $stackPos) {
  17881. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17882. $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
  17883. }, 138 => static function ($self, $stackPos) {
  17884. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17885. $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
  17886. }, 139 => static function ($self, $stackPos) {
  17887. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17888. $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
  17889. }, 140 => static function ($self, $stackPos) {
  17890. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  17891. $self->semValue->type = Stmt\Use_::TYPE_NORMAL;
  17892. }, 141 => static function ($self, $stackPos) {
  17893. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  17894. $self->semValue->type = $self->semStack[$stackPos - (2 - 1)];
  17895. }, 142 => null, 143 => static function ($self, $stackPos) {
  17896. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17897. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17898. }, 144 => static function ($self, $stackPos) {
  17899. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17900. }, 145 => static function ($self, $stackPos) {
  17901. $self->semValue = new Node\Const_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17902. }, 146 => null, 147 => static function ($self, $stackPos) {
  17903. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17904. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17905. }, 148 => static function ($self, $stackPos) {
  17906. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17907. }, 149 => static function ($self, $stackPos) {
  17908. $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17909. }, 150 => static function ($self, $stackPos) {
  17910. $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17911. }, 151 => static function ($self, $stackPos) {
  17912. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  17913. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  17914. }
  17915. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  17916. }, 152 => static function ($self, $stackPos) {
  17917. $self->semValue = array();
  17918. }, 153 => static function ($self, $stackPos) {
  17919. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  17920. if ($nop !== null) {
  17921. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  17922. }
  17923. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  17924. }, 154 => null, 155 => null, 156 => null, 157 => static function ($self, $stackPos) {
  17925. throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17926. }, 158 => static function ($self, $stackPos) {
  17927. $self->semValue = new Stmt\Block($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17928. }, 159 => static function ($self, $stackPos) {
  17929. $self->semValue = new Stmt\If_($self->semStack[$stackPos - (7 - 3)], ['stmts' => $self->semStack[$stackPos - (7 - 5)], 'elseifs' => $self->semStack[$stackPos - (7 - 6)], 'else' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  17930. }, 160 => static function ($self, $stackPos) {
  17931. $self->semValue = new Stmt\If_($self->semStack[$stackPos - (10 - 3)], ['stmts' => $self->semStack[$stackPos - (10 - 6)], 'elseifs' => $self->semStack[$stackPos - (10 - 7)], 'else' => $self->semStack[$stackPos - (10 - 8)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  17932. }, 161 => static function ($self, $stackPos) {
  17933. $self->semValue = new Stmt\While_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  17934. }, 162 => static function ($self, $stackPos) {
  17935. $self->semValue = new Stmt\Do_($self->semStack[$stackPos - (7 - 5)], $self->semStack[$stackPos - (7 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  17936. }, 163 => static function ($self, $stackPos) {
  17937. $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos - (9 - 3)], 'cond' => $self->semStack[$stackPos - (9 - 5)], 'loop' => $self->semStack[$stackPos - (9 - 7)], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  17938. }, 164 => static function ($self, $stackPos) {
  17939. $self->semValue = new Stmt\Switch_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  17940. }, 165 => static function ($self, $stackPos) {
  17941. $self->semValue = new Stmt\Break_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17942. }, 166 => static function ($self, $stackPos) {
  17943. $self->semValue = new Stmt\Continue_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17944. }, 167 => static function ($self, $stackPos) {
  17945. $self->semValue = new Stmt\Return_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17946. }, 168 => static function ($self, $stackPos) {
  17947. $self->semValue = new Stmt\Global_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17948. }, 169 => static function ($self, $stackPos) {
  17949. $self->semValue = new Stmt\Static_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17950. }, 170 => static function ($self, $stackPos) {
  17951. $self->semValue = new Stmt\Echo_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17952. }, 171 => static function ($self, $stackPos) {
  17953. $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  17954. $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos - (1 - 1)));
  17955. }, 172 => static function ($self, $stackPos) {
  17956. $self->semValue = new Stmt\Expression($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  17957. }, 173 => static function ($self, $stackPos) {
  17958. $self->semValue = new Stmt\Unset_($self->semStack[$stackPos - (5 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  17959. }, 174 => static function ($self, $stackPos) {
  17960. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos - (7 - 5)][1], 'stmts' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  17961. }, 175 => static function ($self, $stackPos) {
  17962. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $self->semStack[$stackPos - (9 - 5)], 'byRef' => $self->semStack[$stackPos - (9 - 7)][1], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  17963. }, 176 => static function ($self, $stackPos) {
  17964. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (6 - 3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 4)], $self->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $self->semStack[$stackPos - (6 - 6)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  17965. }, 177 => static function ($self, $stackPos) {
  17966. $self->semValue = new Stmt\Declare_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  17967. }, 178 => static function ($self, $stackPos) {
  17968. $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  17969. $self->checkTryCatch($self->semValue);
  17970. }, 179 => static function ($self, $stackPos) {
  17971. $self->semValue = new Stmt\Goto_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  17972. }, 180 => static function ($self, $stackPos) {
  17973. $self->semValue = new Stmt\Label($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  17974. }, 181 => static function ($self, $stackPos) {
  17975. $self->semValue = null;
  17976. /* means: no statement */
  17977. }, 182 => null, 183 => static function ($self, $stackPos) {
  17978. $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
  17979. }, 184 => static function ($self, $stackPos) {
  17980. if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
  17981. $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
  17982. } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
  17983. $self->semValue = [];
  17984. } else {
  17985. $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
  17986. }
  17987. }, 185 => static function ($self, $stackPos) {
  17988. $self->semValue = array();
  17989. }, 186 => static function ($self, $stackPos) {
  17990. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  17991. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  17992. }, 187 => static function ($self, $stackPos) {
  17993. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  17994. }, 188 => static function ($self, $stackPos) {
  17995. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  17996. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  17997. }, 189 => static function ($self, $stackPos) {
  17998. $self->semValue = new Stmt\Catch_($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 7)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  17999. }, 190 => static function ($self, $stackPos) {
  18000. $self->semValue = null;
  18001. }, 191 => static function ($self, $stackPos) {
  18002. $self->semValue = new Stmt\Finally_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18003. }, 192 => null, 193 => static function ($self, $stackPos) {
  18004. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18005. }, 194 => static function ($self, $stackPos) {
  18006. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18007. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18008. }, 195 => static function ($self, $stackPos) {
  18009. $self->semValue = \false;
  18010. }, 196 => static function ($self, $stackPos) {
  18011. $self->semValue = \true;
  18012. }, 197 => static function ($self, $stackPos) {
  18013. $self->semValue = \false;
  18014. }, 198 => static function ($self, $stackPos) {
  18015. $self->semValue = \true;
  18016. }, 199 => static function ($self, $stackPos) {
  18017. $self->semValue = \false;
  18018. }, 200 => static function ($self, $stackPos) {
  18019. $self->semValue = \true;
  18020. }, 201 => static function ($self, $stackPos) {
  18021. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18022. }, 202 => static function ($self, $stackPos) {
  18023. $self->semValue = [];
  18024. }, 203 => null, 204 => static function ($self, $stackPos) {
  18025. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18026. }, 205 => static function ($self, $stackPos) {
  18027. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18028. }, 206 => static function ($self, $stackPos) {
  18029. $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (8 - 3)], ['byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 5)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18030. }, 207 => static function ($self, $stackPos) {
  18031. $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (9 - 4)], ['byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 6)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  18032. }, 208 => static function ($self, $stackPos) {
  18033. $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (7 - 2)], ['type' => $self->semStack[$stackPos - (7 - 1)], 'extends' => $self->semStack[$stackPos - (7 - 3)], 'implements' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  18034. $self->checkClass($self->semValue, $stackPos - (7 - 2));
  18035. }, 209 => static function ($self, $stackPos) {
  18036. $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (8 - 3)], ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18037. $self->checkClass($self->semValue, $stackPos - (8 - 3));
  18038. }, 210 => static function ($self, $stackPos) {
  18039. $self->semValue = new Stmt\Interface_($self->semStack[$stackPos - (7 - 3)], ['extends' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => $self->semStack[$stackPos - (7 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  18040. $self->checkInterface($self->semValue, $stackPos - (7 - 3));
  18041. }, 211 => static function ($self, $stackPos) {
  18042. $self->semValue = new Stmt\Trait_($self->semStack[$stackPos - (6 - 3)], ['stmts' => $self->semStack[$stackPos - (6 - 5)], 'attrGroups' => $self->semStack[$stackPos - (6 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  18043. }, 212 => static function ($self, $stackPos) {
  18044. $self->semValue = new Stmt\Enum_($self->semStack[$stackPos - (8 - 3)], ['scalarType' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18045. $self->checkEnum($self->semValue, $stackPos - (8 - 3));
  18046. }, 213 => static function ($self, $stackPos) {
  18047. $self->semValue = null;
  18048. }, 214 => static function ($self, $stackPos) {
  18049. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18050. }, 215 => static function ($self, $stackPos) {
  18051. $self->semValue = null;
  18052. }, 216 => static function ($self, $stackPos) {
  18053. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18054. }, 217 => static function ($self, $stackPos) {
  18055. $self->semValue = 0;
  18056. }, 218 => null, 219 => null, 220 => static function ($self, $stackPos) {
  18057. $self->checkClassModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  18058. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  18059. }, 221 => static function ($self, $stackPos) {
  18060. $self->semValue = Modifiers::ABSTRACT;
  18061. }, 222 => static function ($self, $stackPos) {
  18062. $self->semValue = Modifiers::FINAL;
  18063. }, 223 => static function ($self, $stackPos) {
  18064. $self->semValue = Modifiers::READONLY;
  18065. }, 224 => static function ($self, $stackPos) {
  18066. $self->semValue = null;
  18067. }, 225 => static function ($self, $stackPos) {
  18068. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18069. }, 226 => static function ($self, $stackPos) {
  18070. $self->semValue = array();
  18071. }, 227 => static function ($self, $stackPos) {
  18072. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18073. }, 228 => static function ($self, $stackPos) {
  18074. $self->semValue = array();
  18075. }, 229 => static function ($self, $stackPos) {
  18076. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18077. }, 230 => null, 231 => static function ($self, $stackPos) {
  18078. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18079. }, 232 => static function ($self, $stackPos) {
  18080. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18081. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18082. }, 233 => null, 234 => static function ($self, $stackPos) {
  18083. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18084. }, 235 => null, 236 => static function ($self, $stackPos) {
  18085. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18086. }, 237 => static function ($self, $stackPos) {
  18087. if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
  18088. $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
  18089. } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
  18090. $self->semValue = [];
  18091. } else {
  18092. $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
  18093. }
  18094. }, 238 => static function ($self, $stackPos) {
  18095. $self->semValue = null;
  18096. }, 239 => static function ($self, $stackPos) {
  18097. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18098. }, 240 => null, 241 => static function ($self, $stackPos) {
  18099. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18100. }, 242 => static function ($self, $stackPos) {
  18101. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18102. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18103. }, 243 => static function ($self, $stackPos) {
  18104. $self->semValue = new Node\DeclareItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18105. }, 244 => static function ($self, $stackPos) {
  18106. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18107. }, 245 => static function ($self, $stackPos) {
  18108. $self->semValue = $self->semStack[$stackPos - (4 - 3)];
  18109. }, 246 => static function ($self, $stackPos) {
  18110. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18111. }, 247 => static function ($self, $stackPos) {
  18112. $self->semValue = $self->semStack[$stackPos - (5 - 3)];
  18113. }, 248 => static function ($self, $stackPos) {
  18114. $self->semValue = array();
  18115. }, 249 => static function ($self, $stackPos) {
  18116. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18117. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18118. }, 250 => static function ($self, $stackPos) {
  18119. $self->semValue = new Stmt\Case_($self->semStack[$stackPos - (4 - 2)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18120. }, 251 => static function ($self, $stackPos) {
  18121. $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18122. }, 252 => null, 253 => null, 254 => static function ($self, $stackPos) {
  18123. $self->semValue = new Expr\Match_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  18124. }, 255 => static function ($self, $stackPos) {
  18125. $self->semValue = [];
  18126. }, 256 => null, 257 => static function ($self, $stackPos) {
  18127. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18128. }, 258 => static function ($self, $stackPos) {
  18129. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18130. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18131. }, 259 => static function ($self, $stackPos) {
  18132. $self->semValue = new Node\MatchArm($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18133. }, 260 => static function ($self, $stackPos) {
  18134. $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18135. }, 261 => static function ($self, $stackPos) {
  18136. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  18137. }, 262 => static function ($self, $stackPos) {
  18138. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18139. }, 263 => static function ($self, $stackPos) {
  18140. $self->semValue = array();
  18141. }, 264 => static function ($self, $stackPos) {
  18142. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18143. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18144. }, 265 => static function ($self, $stackPos) {
  18145. $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18146. }, 266 => static function ($self, $stackPos) {
  18147. $self->semValue = array();
  18148. }, 267 => static function ($self, $stackPos) {
  18149. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18150. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18151. }, 268 => static function ($self, $stackPos) {
  18152. $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  18153. $self->fixupAlternativeElse($self->semValue);
  18154. }, 269 => static function ($self, $stackPos) {
  18155. $self->semValue = null;
  18156. }, 270 => static function ($self, $stackPos) {
  18157. $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18158. }, 271 => static function ($self, $stackPos) {
  18159. $self->semValue = null;
  18160. }, 272 => static function ($self, $stackPos) {
  18161. $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18162. $self->fixupAlternativeElse($self->semValue);
  18163. }, 273 => static function ($self, $stackPos) {
  18164. $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
  18165. }, 274 => static function ($self, $stackPos) {
  18166. $self->semValue = array($self->semStack[$stackPos - (2 - 2)], \true);
  18167. }, 275 => static function ($self, $stackPos) {
  18168. $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
  18169. }, 276 => static function ($self, $stackPos) {
  18170. $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos - (1 - 1)]), \false);
  18171. }, 277 => null, 278 => static function ($self, $stackPos) {
  18172. $self->semValue = array();
  18173. }, 279 => static function ($self, $stackPos) {
  18174. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18175. }, 280 => static function ($self, $stackPos) {
  18176. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18177. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18178. }, 281 => static function ($self, $stackPos) {
  18179. $self->semValue = 0;
  18180. }, 282 => static function ($self, $stackPos) {
  18181. $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  18182. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  18183. }, 283 => static function ($self, $stackPos) {
  18184. $self->semValue = Modifiers::PUBLIC;
  18185. }, 284 => static function ($self, $stackPos) {
  18186. $self->semValue = Modifiers::PROTECTED;
  18187. }, 285 => static function ($self, $stackPos) {
  18188. $self->semValue = Modifiers::PRIVATE;
  18189. }, 286 => static function ($self, $stackPos) {
  18190. $self->semValue = Modifiers::PUBLIC_SET;
  18191. }, 287 => static function ($self, $stackPos) {
  18192. $self->semValue = Modifiers::PROTECTED_SET;
  18193. }, 288 => static function ($self, $stackPos) {
  18194. $self->semValue = Modifiers::PRIVATE_SET;
  18195. }, 289 => static function ($self, $stackPos) {
  18196. $self->semValue = Modifiers::READONLY;
  18197. }, 290 => static function ($self, $stackPos) {
  18198. $self->semValue = new Node\Param($self->semStack[$stackPos - (7 - 6)], null, $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 4)], $self->semStack[$stackPos - (7 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 7)]);
  18199. $self->checkParam($self->semValue);
  18200. }, 291 => static function ($self, $stackPos) {
  18201. $self->semValue = new Node\Param($self->semStack[$stackPos - (9 - 6)], $self->semStack[$stackPos - (9 - 8)], $self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 4)], $self->semStack[$stackPos - (9 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (9 - 2)], $self->semStack[$stackPos - (9 - 1)], $self->semStack[$stackPos - (9 - 9)]);
  18202. $self->checkParam($self->semValue);
  18203. }, 292 => static function ($self, $stackPos) {
  18204. $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 4)], $self->semStack[$stackPos - (6 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 1)]);
  18205. }, 293 => null, 294 => static function ($self, $stackPos) {
  18206. $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18207. }, 295 => static function ($self, $stackPos) {
  18208. $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18209. }, 296 => null, 297 => null, 298 => static function ($self, $stackPos) {
  18210. $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18211. }, 299 => static function ($self, $stackPos) {
  18212. $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos - (1 - 1)]);
  18213. }, 300 => static function ($self, $stackPos) {
  18214. $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18215. }, 301 => static function ($self, $stackPos) {
  18216. $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18217. }, 302 => null, 303 => static function ($self, $stackPos) {
  18218. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18219. }, 304 => static function ($self, $stackPos) {
  18220. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  18221. }, 305 => static function ($self, $stackPos) {
  18222. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18223. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18224. }, 306 => null, 307 => static function ($self, $stackPos) {
  18225. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18226. }, 308 => static function ($self, $stackPos) {
  18227. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  18228. }, 309 => static function ($self, $stackPos) {
  18229. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18230. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18231. }, 310 => static function ($self, $stackPos) {
  18232. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  18233. }, 311 => static function ($self, $stackPos) {
  18234. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18235. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18236. }, 312 => static function ($self, $stackPos) {
  18237. $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18238. }, 313 => static function ($self, $stackPos) {
  18239. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  18240. }, 314 => static function ($self, $stackPos) {
  18241. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18242. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18243. }, 315 => static function ($self, $stackPos) {
  18244. $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18245. }, 316 => null, 317 => static function ($self, $stackPos) {
  18246. $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18247. }, 318 => static function ($self, $stackPos) {
  18248. $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18249. }, 319 => null, 320 => static function ($self, $stackPos) {
  18250. $self->semValue = null;
  18251. }, 321 => null, 322 => static function ($self, $stackPos) {
  18252. $self->semValue = null;
  18253. }, 323 => static function ($self, $stackPos) {
  18254. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  18255. }, 324 => static function ($self, $stackPos) {
  18256. $self->semValue = null;
  18257. }, 325 => static function ($self, $stackPos) {
  18258. $self->semValue = array();
  18259. }, 326 => static function ($self, $stackPos) {
  18260. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  18261. }, 327 => static function ($self, $stackPos) {
  18262. $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
  18263. }, 328 => static function ($self, $stackPos) {
  18264. $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18265. }, 329 => static function ($self, $stackPos) {
  18266. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18267. }, 330 => static function ($self, $stackPos) {
  18268. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18269. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18270. }, 331 => static function ($self, $stackPos) {
  18271. $self->semValue = new Node\Arg($self->semStack[$stackPos - (1 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18272. }, 332 => static function ($self, $stackPos) {
  18273. $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \true, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18274. }, 333 => static function ($self, $stackPos) {
  18275. $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \false, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18276. }, 334 => static function ($self, $stackPos) {
  18277. $self->semValue = new Node\Arg($self->semStack[$stackPos - (3 - 3)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (3 - 1)]);
  18278. }, 335 => null, 336 => static function ($self, $stackPos) {
  18279. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18280. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18281. }, 337 => static function ($self, $stackPos) {
  18282. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18283. }, 338 => null, 339 => null, 340 => static function ($self, $stackPos) {
  18284. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18285. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18286. }, 341 => static function ($self, $stackPos) {
  18287. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18288. }, 342 => static function ($self, $stackPos) {
  18289. $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18290. }, 343 => static function ($self, $stackPos) {
  18291. $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18292. }, 344 => static function ($self, $stackPos) {
  18293. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  18294. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18295. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18296. } else {
  18297. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18298. }
  18299. }, 345 => static function ($self, $stackPos) {
  18300. $self->semValue = array();
  18301. }, 346 => static function ($self, $stackPos) {
  18302. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  18303. if ($nop !== null) {
  18304. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  18305. }
  18306. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  18307. }, 347 => static function ($self, $stackPos) {
  18308. $self->semValue = new Stmt\Property($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 1)]);
  18309. }, 348 => static function ($self, $stackPos) {
  18310. $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 1)]);
  18311. $self->checkClassConst($self->semValue, $stackPos - (5 - 2));
  18312. }, 349 => static function ($self, $stackPos) {
  18313. $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 1)], $self->semStack[$stackPos - (6 - 4)]);
  18314. $self->checkClassConst($self->semValue, $stackPos - (6 - 2));
  18315. }, 350 => static function ($self, $stackPos) {
  18316. $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos - (10 - 5)], ['type' => $self->semStack[$stackPos - (10 - 2)], 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 7)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  18317. $self->checkClassMethod($self->semValue, $stackPos - (10 - 2));
  18318. }, 351 => static function ($self, $stackPos) {
  18319. $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18320. }, 352 => static function ($self, $stackPos) {
  18321. $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18322. }, 353 => static function ($self, $stackPos) {
  18323. $self->semValue = null;
  18324. /* will be skipped */
  18325. }, 354 => static function ($self, $stackPos) {
  18326. $self->semValue = array();
  18327. }, 355 => static function ($self, $stackPos) {
  18328. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18329. }, 356 => static function ($self, $stackPos) {
  18330. $self->semValue = array();
  18331. }, 357 => static function ($self, $stackPos) {
  18332. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18333. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18334. }, 358 => static function ($self, $stackPos) {
  18335. $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18336. }, 359 => static function ($self, $stackPos) {
  18337. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (5 - 1)][0], $self->semStack[$stackPos - (5 - 1)][1], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18338. }, 360 => static function ($self, $stackPos) {
  18339. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18340. }, 361 => static function ($self, $stackPos) {
  18341. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18342. }, 362 => static function ($self, $stackPos) {
  18343. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18344. }, 363 => static function ($self, $stackPos) {
  18345. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  18346. }, 364 => null, 365 => static function ($self, $stackPos) {
  18347. $self->semValue = array(null, $self->semStack[$stackPos - (1 - 1)]);
  18348. }, 366 => static function ($self, $stackPos) {
  18349. $self->semValue = null;
  18350. }, 367 => null, 368 => null, 369 => static function ($self, $stackPos) {
  18351. $self->semValue = 0;
  18352. }, 370 => static function ($self, $stackPos) {
  18353. $self->semValue = 0;
  18354. }, 371 => null, 372 => null, 373 => static function ($self, $stackPos) {
  18355. $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  18356. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  18357. }, 374 => static function ($self, $stackPos) {
  18358. $self->semValue = Modifiers::PUBLIC;
  18359. }, 375 => static function ($self, $stackPos) {
  18360. $self->semValue = Modifiers::PROTECTED;
  18361. }, 376 => static function ($self, $stackPos) {
  18362. $self->semValue = Modifiers::PRIVATE;
  18363. }, 377 => static function ($self, $stackPos) {
  18364. $self->semValue = Modifiers::PUBLIC_SET;
  18365. }, 378 => static function ($self, $stackPos) {
  18366. $self->semValue = Modifiers::PROTECTED_SET;
  18367. }, 379 => static function ($self, $stackPos) {
  18368. $self->semValue = Modifiers::PRIVATE_SET;
  18369. }, 380 => static function ($self, $stackPos) {
  18370. $self->semValue = Modifiers::STATIC;
  18371. }, 381 => static function ($self, $stackPos) {
  18372. $self->semValue = Modifiers::ABSTRACT;
  18373. }, 382 => static function ($self, $stackPos) {
  18374. $self->semValue = Modifiers::FINAL;
  18375. }, 383 => static function ($self, $stackPos) {
  18376. $self->semValue = Modifiers::READONLY;
  18377. }, 384 => null, 385 => static function ($self, $stackPos) {
  18378. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18379. }, 386 => static function ($self, $stackPos) {
  18380. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18381. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18382. }, 387 => static function ($self, $stackPos) {
  18383. $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18384. }, 388 => static function ($self, $stackPos) {
  18385. $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18386. }, 389 => static function ($self, $stackPos) {
  18387. $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18388. }, 390 => static function ($self, $stackPos) {
  18389. $self->semValue = [];
  18390. }, 391 => static function ($self, $stackPos) {
  18391. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18392. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18393. }, 392 => static function ($self, $stackPos) {
  18394. $self->semValue = [];
  18395. }, 393 => static function ($self, $stackPos) {
  18396. $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 5)], ['flags' => $self->semStack[$stackPos - (5 - 2)], 'byRef' => $self->semStack[$stackPos - (5 - 3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos - (5 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18397. $self->checkPropertyHook($self->semValue, null);
  18398. }, 394 => static function ($self, $stackPos) {
  18399. $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 8)], ['flags' => $self->semStack[$stackPos - (8 - 2)], 'byRef' => $self->semStack[$stackPos - (8 - 3)], 'params' => $self->semStack[$stackPos - (8 - 6)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18400. $self->checkPropertyHook($self->semValue, $stackPos - (8 - 5));
  18401. }, 395 => static function ($self, $stackPos) {
  18402. $self->semValue = null;
  18403. }, 396 => static function ($self, $stackPos) {
  18404. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18405. }, 397 => static function ($self, $stackPos) {
  18406. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18407. }, 398 => static function ($self, $stackPos) {
  18408. $self->semValue = 0;
  18409. }, 399 => static function ($self, $stackPos) {
  18410. $self->checkPropertyHookModifiers($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  18411. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  18412. }, 400 => null, 401 => null, 402 => static function ($self, $stackPos) {
  18413. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18414. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18415. }, 403 => static function ($self, $stackPos) {
  18416. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18417. }, 404 => static function ($self, $stackPos) {
  18418. $self->semValue = array();
  18419. }, 405 => null, 406 => null, 407 => static function ($self, $stackPos) {
  18420. $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18421. }, 408 => static function ($self, $stackPos) {
  18422. $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos - (3 - 1)]), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18423. }, 409 => static function ($self, $stackPos) {
  18424. $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18425. }, 410 => static function ($self, $stackPos) {
  18426. $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18427. }, 411 => static function ($self, $stackPos) {
  18428. $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18429. if (!$self->phpVersion->allowsAssignNewByReference()) {
  18430. $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
  18431. }
  18432. }, 412 => null, 413 => null, 414 => static function ($self, $stackPos) {
  18433. $self->semValue = new Expr\Clone_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18434. }, 415 => static function ($self, $stackPos) {
  18435. $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18436. }, 416 => static function ($self, $stackPos) {
  18437. $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18438. }, 417 => static function ($self, $stackPos) {
  18439. $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18440. }, 418 => static function ($self, $stackPos) {
  18441. $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18442. }, 419 => static function ($self, $stackPos) {
  18443. $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18444. }, 420 => static function ($self, $stackPos) {
  18445. $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18446. }, 421 => static function ($self, $stackPos) {
  18447. $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18448. }, 422 => static function ($self, $stackPos) {
  18449. $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18450. }, 423 => static function ($self, $stackPos) {
  18451. $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18452. }, 424 => static function ($self, $stackPos) {
  18453. $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18454. }, 425 => static function ($self, $stackPos) {
  18455. $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18456. }, 426 => static function ($self, $stackPos) {
  18457. $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18458. }, 427 => static function ($self, $stackPos) {
  18459. $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18460. }, 428 => static function ($self, $stackPos) {
  18461. $self->semValue = new Expr\PostInc($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18462. }, 429 => static function ($self, $stackPos) {
  18463. $self->semValue = new Expr\PreInc($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18464. }, 430 => static function ($self, $stackPos) {
  18465. $self->semValue = new Expr\PostDec($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18466. }, 431 => static function ($self, $stackPos) {
  18467. $self->semValue = new Expr\PreDec($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18468. }, 432 => static function ($self, $stackPos) {
  18469. $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18470. }, 433 => static function ($self, $stackPos) {
  18471. $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18472. }, 434 => static function ($self, $stackPos) {
  18473. $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18474. }, 435 => static function ($self, $stackPos) {
  18475. $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18476. }, 436 => static function ($self, $stackPos) {
  18477. $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18478. }, 437 => static function ($self, $stackPos) {
  18479. $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18480. }, 438 => static function ($self, $stackPos) {
  18481. $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18482. }, 439 => static function ($self, $stackPos) {
  18483. $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18484. }, 440 => static function ($self, $stackPos) {
  18485. $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18486. }, 441 => static function ($self, $stackPos) {
  18487. $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18488. }, 442 => static function ($self, $stackPos) {
  18489. $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18490. }, 443 => static function ($self, $stackPos) {
  18491. $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18492. }, 444 => static function ($self, $stackPos) {
  18493. $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18494. }, 445 => static function ($self, $stackPos) {
  18495. $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18496. }, 446 => static function ($self, $stackPos) {
  18497. $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18498. }, 447 => static function ($self, $stackPos) {
  18499. $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18500. }, 448 => static function ($self, $stackPos) {
  18501. $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18502. }, 449 => static function ($self, $stackPos) {
  18503. $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18504. }, 450 => static function ($self, $stackPos) {
  18505. $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18506. }, 451 => static function ($self, $stackPos) {
  18507. $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18508. }, 452 => static function ($self, $stackPos) {
  18509. $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18510. }, 453 => static function ($self, $stackPos) {
  18511. $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18512. }, 454 => static function ($self, $stackPos) {
  18513. $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18514. }, 455 => static function ($self, $stackPos) {
  18515. $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18516. }, 456 => static function ($self, $stackPos) {
  18517. $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18518. }, 457 => static function ($self, $stackPos) {
  18519. $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18520. }, 458 => static function ($self, $stackPos) {
  18521. $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18522. }, 459 => static function ($self, $stackPos) {
  18523. $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18524. }, 460 => static function ($self, $stackPos) {
  18525. $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18526. }, 461 => static function ($self, $stackPos) {
  18527. $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18528. }, 462 => static function ($self, $stackPos) {
  18529. $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18530. }, 463 => static function ($self, $stackPos) {
  18531. $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18532. }, 464 => static function ($self, $stackPos) {
  18533. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18534. }, 465 => static function ($self, $stackPos) {
  18535. $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18536. }, 466 => static function ($self, $stackPos) {
  18537. $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (4 - 1)], null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18538. }, 467 => static function ($self, $stackPos) {
  18539. $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18540. }, 468 => static function ($self, $stackPos) {
  18541. $self->semValue = new Expr\Isset_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18542. }, 469 => static function ($self, $stackPos) {
  18543. $self->semValue = new Expr\Empty_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18544. }, 470 => static function ($self, $stackPos) {
  18545. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18546. }, 471 => static function ($self, $stackPos) {
  18547. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18548. }, 472 => static function ($self, $stackPos) {
  18549. $self->semValue = new Expr\Eval_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18550. }, 473 => static function ($self, $stackPos) {
  18551. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18552. }, 474 => static function ($self, $stackPos) {
  18553. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18554. }, 475 => static function ($self, $stackPos) {
  18555. $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18556. }, 476 => static function ($self, $stackPos) {
  18557. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
  18558. $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos - (2 - 1)]);
  18559. $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos - (2 - 2)], $attrs);
  18560. }, 477 => static function ($self, $stackPos) {
  18561. $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18562. }, 478 => static function ($self, $stackPos) {
  18563. $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18564. }, 479 => static function ($self, $stackPos) {
  18565. $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18566. }, 480 => static function ($self, $stackPos) {
  18567. $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18568. }, 481 => static function ($self, $stackPos) {
  18569. $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18570. }, 482 => static function ($self, $stackPos) {
  18571. $self->semValue = $self->createExitExpr($self->semStack[$stackPos - (2 - 1)], $stackPos - (2 - 1), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18572. }, 483 => static function ($self, $stackPos) {
  18573. $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18574. }, 484 => null, 485 => static function ($self, $stackPos) {
  18575. $self->semValue = new Expr\ShellExec($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18576. }, 486 => static function ($self, $stackPos) {
  18577. $self->semValue = new Expr\Print_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18578. }, 487 => static function ($self, $stackPos) {
  18579. $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18580. }, 488 => static function ($self, $stackPos) {
  18581. $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (2 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18582. }, 489 => static function ($self, $stackPos) {
  18583. $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18584. }, 490 => static function ($self, $stackPos) {
  18585. $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18586. }, 491 => static function ($self, $stackPos) {
  18587. $self->semValue = new Expr\Throw_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18588. }, 492 => static function ($self, $stackPos) {
  18589. $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'returnType' => $self->semStack[$stackPos - (8 - 6)], 'expr' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18590. }, 493 => static function ($self, $stackPos) {
  18591. $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  18592. }, 494 => static function ($self, $stackPos) {
  18593. $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'uses' => $self->semStack[$stackPos - (8 - 6)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  18594. }, 495 => static function ($self, $stackPos) {
  18595. $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  18596. }, 496 => static function ($self, $stackPos) {
  18597. $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  18598. }, 497 => static function ($self, $stackPos) {
  18599. $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'returnType' => $self->semStack[$stackPos - (10 - 8)], 'expr' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  18600. }, 498 => static function ($self, $stackPos) {
  18601. $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  18602. }, 499 => static function ($self, $stackPos) {
  18603. $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'uses' => $self->semStack[$stackPos - (10 - 8)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  18604. }, 500 => static function ($self, $stackPos) {
  18605. $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos - (8 - 3)]);
  18606. $self->checkClass($self->semValue[0], -1);
  18607. }, 501 => static function ($self, $stackPos) {
  18608. $self->semValue = new Expr\New_($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18609. }, 502 => static function ($self, $stackPos) {
  18610. list($class, $ctorArgs) = $self->semStack[$stackPos - (2 - 2)];
  18611. $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18612. }, 503 => static function ($self, $stackPos) {
  18613. $self->semValue = new Expr\New_($self->semStack[$stackPos - (2 - 2)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18614. }, 504 => null, 505 => null, 506 => static function ($self, $stackPos) {
  18615. $self->semValue = array();
  18616. }, 507 => static function ($self, $stackPos) {
  18617. $self->semValue = $self->semStack[$stackPos - (4 - 3)];
  18618. }, 508 => null, 509 => static function ($self, $stackPos) {
  18619. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18620. }, 510 => static function ($self, $stackPos) {
  18621. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18622. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18623. }, 511 => static function ($self, $stackPos) {
  18624. $self->semValue = new Node\ClosureUse($self->semStack[$stackPos - (2 - 2)], $self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18625. }, 512 => static function ($self, $stackPos) {
  18626. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18627. }, 513 => static function ($self, $stackPos) {
  18628. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18629. }, 514 => static function ($self, $stackPos) {
  18630. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18631. }, 515 => static function ($self, $stackPos) {
  18632. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18633. }, 516 => static function ($self, $stackPos) {
  18634. $self->semValue = new Expr\StaticCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18635. }, 517 => static function ($self, $stackPos) {
  18636. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18637. }, 518 => null, 519 => static function ($self, $stackPos) {
  18638. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18639. }, 520 => static function ($self, $stackPos) {
  18640. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18641. }, 521 => static function ($self, $stackPos) {
  18642. $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18643. }, 522 => static function ($self, $stackPos) {
  18644. $self->semValue = new Name\Relative(substr($self->semStack[$stackPos - (1 - 1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18645. }, 523 => null, 524 => null, 525 => static function ($self, $stackPos) {
  18646. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18647. }, 526 => static function ($self, $stackPos) {
  18648. $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18649. $self->errorState = 2;
  18650. }, 527 => null, 528 => null, 529 => static function ($self, $stackPos) {
  18651. $self->semValue = array();
  18652. }, 530 => static function ($self, $stackPos) {
  18653. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18654. foreach ($self->semValue as $s) {
  18655. if ($s instanceof Node\InterpolatedStringPart) {
  18656. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
  18657. }
  18658. }
  18659. }, 531 => static function ($self, $stackPos) {
  18660. foreach ($self->semStack[$stackPos - (1 - 1)] as $s) {
  18661. if ($s instanceof Node\InterpolatedStringPart) {
  18662. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
  18663. }
  18664. }
  18665. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  18666. }, 532 => static function ($self, $stackPos) {
  18667. $self->semValue = array();
  18668. }, 533 => null, 534 => static function ($self, $stackPos) {
  18669. $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18670. }, 535 => static function ($self, $stackPos) {
  18671. $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18672. }, 536 => static function ($self, $stackPos) {
  18673. $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18674. }, 537 => static function ($self, $stackPos) {
  18675. $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18676. }, 538 => static function ($self, $stackPos) {
  18677. $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18678. }, 539 => static function ($self, $stackPos) {
  18679. $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18680. }, 540 => static function ($self, $stackPos) {
  18681. $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18682. }, 541 => static function ($self, $stackPos) {
  18683. $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18684. }, 542 => static function ($self, $stackPos) {
  18685. $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18686. }, 543 => static function ($self, $stackPos) {
  18687. $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18688. }, 544 => static function ($self, $stackPos) {
  18689. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18690. }, 545 => static function ($self, $stackPos) {
  18691. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  18692. }, 546 => static function ($self, $stackPos) {
  18693. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)])), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18694. $self->errorState = 2;
  18695. }, 547 => static function ($self, $stackPos) {
  18696. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
  18697. $attrs['kind'] = Expr\Array_::KIND_SHORT;
  18698. $self->semValue = new Expr\Array_($self->semStack[$stackPos - (3 - 2)], $attrs);
  18699. }, 548 => static function ($self, $stackPos) {
  18700. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]);
  18701. $attrs['kind'] = Expr\Array_::KIND_LONG;
  18702. $self->semValue = new Expr\Array_($self->semStack[$stackPos - (4 - 3)], $attrs);
  18703. $self->createdArrays->attach($self->semValue);
  18704. }, 549 => static function ($self, $stackPos) {
  18705. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  18706. $self->createdArrays->attach($self->semValue);
  18707. }, 550 => static function ($self, $stackPos) {
  18708. $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes());
  18709. }, 551 => static function ($self, $stackPos) {
  18710. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
  18711. $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
  18712. foreach ($self->semStack[$stackPos - (3 - 2)] as $s) {
  18713. if ($s instanceof Node\InterpolatedStringPart) {
  18714. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes());
  18715. }
  18716. }
  18717. $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos - (3 - 2)], $attrs);
  18718. }, 552 => static function ($self, $stackPos) {
  18719. $self->semValue = $self->parseLNumber($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals());
  18720. }, 553 => static function ($self, $stackPos) {
  18721. $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18722. }, 554 => null, 555 => null, 556 => null, 557 => static function ($self, $stackPos) {
  18723. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
  18724. }, 558 => static function ($self, $stackPos) {
  18725. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (2 - 1)], '', $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 2)], $self->tokenEndStack[$stackPos - (2 - 2)]), \true);
  18726. }, 559 => static function ($self, $stackPos) {
  18727. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
  18728. }, 560 => static function ($self, $stackPos) {
  18729. $self->semValue = null;
  18730. }, 561 => null, 562 => null, 563 => static function ($self, $stackPos) {
  18731. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18732. }, 564 => null, 565 => null, 566 => null, 567 => null, 568 => null, 569 => null, 570 => static function ($self, $stackPos) {
  18733. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18734. }, 571 => null, 572 => null, 573 => null, 574 => static function ($self, $stackPos) {
  18735. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18736. }, 575 => static function ($self, $stackPos) {
  18737. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18738. }, 576 => null, 577 => static function ($self, $stackPos) {
  18739. $self->semValue = new Expr\MethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18740. }, 578 => static function ($self, $stackPos) {
  18741. $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18742. }, 579 => static function ($self, $stackPos) {
  18743. $self->semValue = null;
  18744. }, 580 => null, 581 => null, 582 => null, 583 => static function ($self, $stackPos) {
  18745. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18746. }, 584 => static function ($self, $stackPos) {
  18747. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18748. }, 585 => null, 586 => static function ($self, $stackPos) {
  18749. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18750. }, 587 => static function ($self, $stackPos) {
  18751. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18752. }, 588 => static function ($self, $stackPos) {
  18753. $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18754. $self->errorState = 2;
  18755. }, 589 => static function ($self, $stackPos) {
  18756. $var = $self->semStack[$stackPos - (1 - 1)]->name;
  18757. $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])) : $var;
  18758. }, 590 => static function ($self, $stackPos) {
  18759. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18760. }, 591 => null, 592 => static function ($self, $stackPos) {
  18761. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18762. }, 593 => static function ($self, $stackPos) {
  18763. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18764. }, 594 => static function ($self, $stackPos) {
  18765. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18766. }, 595 => static function ($self, $stackPos) {
  18767. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18768. }, 596 => static function ($self, $stackPos) {
  18769. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18770. }, 597 => static function ($self, $stackPos) {
  18771. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18772. }, 598 => null, 599 => static function ($self, $stackPos) {
  18773. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18774. }, 600 => null, 601 => null, 602 => static function ($self, $stackPos) {
  18775. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18776. }, 603 => null, 604 => static function ($self, $stackPos) {
  18777. $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18778. $self->errorState = 2;
  18779. }, 605 => static function ($self, $stackPos) {
  18780. $self->semValue = new Expr\List_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18781. $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST);
  18782. $self->postprocessList($self->semValue);
  18783. }, 606 => static function ($self, $stackPos) {
  18784. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  18785. $end = count($self->semValue) - 1;
  18786. if ($self->semValue[$end]->value instanceof Expr\Error) {
  18787. array_pop($self->semValue);
  18788. }
  18789. }, 607 => null, 608 => static function ($self, $stackPos) {
  18790. /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */
  18791. }, 609 => static function ($self, $stackPos) {
  18792. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  18793. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  18794. }, 610 => static function ($self, $stackPos) {
  18795. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18796. }, 611 => static function ($self, $stackPos) {
  18797. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18798. }, 612 => static function ($self, $stackPos) {
  18799. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18800. }, 613 => static function ($self, $stackPos) {
  18801. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18802. }, 614 => static function ($self, $stackPos) {
  18803. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18804. }, 615 => static function ($self, $stackPos) {
  18805. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 1)], \true, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18806. }, 616 => static function ($self, $stackPos) {
  18807. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18808. }, 617 => static function ($self, $stackPos) {
  18809. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), \true);
  18810. }, 618 => static function ($self, $stackPos) {
  18811. /* Create an Error node now to remember the position. We'll later either report an error,
  18812. or convert this into a null element, depending on whether this is a creation or destructuring context. */
  18813. $attrs = $self->createEmptyElemAttributes($self->tokenPos);
  18814. $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs);
  18815. }, 619 => static function ($self, $stackPos) {
  18816. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18817. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18818. }, 620 => static function ($self, $stackPos) {
  18819. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  18820. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  18821. }, 621 => static function ($self, $stackPos) {
  18822. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  18823. }, 622 => static function ($self, $stackPos) {
  18824. $self->semValue = array($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)]);
  18825. }, 623 => static function ($self, $stackPos) {
  18826. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
  18827. $attrs['rawValue'] = $self->semStack[$stackPos - (1 - 1)];
  18828. $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos - (1 - 1)], $attrs);
  18829. }, 624 => static function ($self, $stackPos) {
  18830. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18831. }, 625 => null, 626 => static function ($self, $stackPos) {
  18832. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  18833. }, 627 => static function ($self, $stackPos) {
  18834. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18835. }, 628 => static function ($self, $stackPos) {
  18836. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18837. }, 629 => static function ($self, $stackPos) {
  18838. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18839. }, 630 => static function ($self, $stackPos) {
  18840. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  18841. }, 631 => static function ($self, $stackPos) {
  18842. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  18843. }, 632 => static function ($self, $stackPos) {
  18844. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  18845. }, 633 => static function ($self, $stackPos) {
  18846. $self->semValue = new Scalar\String_($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18847. }, 634 => static function ($self, $stackPos) {
  18848. $self->semValue = $self->parseNumString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  18849. }, 635 => static function ($self, $stackPos) {
  18850. $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  18851. }, 636 => null];
  18852. }
  18853. }
  18854. <?php
  18855. declare (strict_types=1);
  18856. namespace PHPUnitPHAR\PhpParser\Parser;
  18857. use PHPUnitPHAR\PhpParser\Error;
  18858. use PHPUnitPHAR\PhpParser\Modifiers;
  18859. use PHPUnitPHAR\PhpParser\Node;
  18860. use PHPUnitPHAR\PhpParser\Node\Expr;
  18861. use PHPUnitPHAR\PhpParser\Node\Name;
  18862. use PHPUnitPHAR\PhpParser\Node\Scalar;
  18863. use PHPUnitPHAR\PhpParser\Node\Stmt;
  18864. /* This is an automatically GENERATED file, which should not be manually edited.
  18865. * Instead edit one of the following:
  18866. * * the grammar file grammar/php.y
  18867. * * the skeleton file grammar/parser.template
  18868. * * the preprocessing script grammar/rebuildParsers.php
  18869. */
  18870. class Php8 extends \PHPUnitPHAR\PhpParser\ParserAbstract
  18871. {
  18872. public const YYERRTOK = 256;
  18873. public const T_THROW = 257;
  18874. public const T_INCLUDE = 258;
  18875. public const T_INCLUDE_ONCE = 259;
  18876. public const T_EVAL = 260;
  18877. public const T_REQUIRE = 261;
  18878. public const T_REQUIRE_ONCE = 262;
  18879. public const T_LOGICAL_OR = 263;
  18880. public const T_LOGICAL_XOR = 264;
  18881. public const T_LOGICAL_AND = 265;
  18882. public const T_PRINT = 266;
  18883. public const T_YIELD = 267;
  18884. public const T_DOUBLE_ARROW = 268;
  18885. public const T_YIELD_FROM = 269;
  18886. public const T_PLUS_EQUAL = 270;
  18887. public const T_MINUS_EQUAL = 271;
  18888. public const T_MUL_EQUAL = 272;
  18889. public const T_DIV_EQUAL = 273;
  18890. public const T_CONCAT_EQUAL = 274;
  18891. public const T_MOD_EQUAL = 275;
  18892. public const T_AND_EQUAL = 276;
  18893. public const T_OR_EQUAL = 277;
  18894. public const T_XOR_EQUAL = 278;
  18895. public const T_SL_EQUAL = 279;
  18896. public const T_SR_EQUAL = 280;
  18897. public const T_POW_EQUAL = 281;
  18898. public const T_COALESCE_EQUAL = 282;
  18899. public const T_COALESCE = 283;
  18900. public const T_BOOLEAN_OR = 284;
  18901. public const T_BOOLEAN_AND = 285;
  18902. public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 286;
  18903. public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 287;
  18904. public const T_IS_EQUAL = 288;
  18905. public const T_IS_NOT_EQUAL = 289;
  18906. public const T_IS_IDENTICAL = 290;
  18907. public const T_IS_NOT_IDENTICAL = 291;
  18908. public const T_SPACESHIP = 292;
  18909. public const T_IS_SMALLER_OR_EQUAL = 293;
  18910. public const T_IS_GREATER_OR_EQUAL = 294;
  18911. public const T_SL = 295;
  18912. public const T_SR = 296;
  18913. public const T_INSTANCEOF = 297;
  18914. public const T_INC = 298;
  18915. public const T_DEC = 299;
  18916. public const T_INT_CAST = 300;
  18917. public const T_DOUBLE_CAST = 301;
  18918. public const T_STRING_CAST = 302;
  18919. public const T_ARRAY_CAST = 303;
  18920. public const T_OBJECT_CAST = 304;
  18921. public const T_BOOL_CAST = 305;
  18922. public const T_UNSET_CAST = 306;
  18923. public const T_POW = 307;
  18924. public const T_NEW = 308;
  18925. public const T_CLONE = 309;
  18926. public const T_EXIT = 310;
  18927. public const T_IF = 311;
  18928. public const T_ELSEIF = 312;
  18929. public const T_ELSE = 313;
  18930. public const T_ENDIF = 314;
  18931. public const T_LNUMBER = 315;
  18932. public const T_DNUMBER = 316;
  18933. public const T_STRING = 317;
  18934. public const T_STRING_VARNAME = 318;
  18935. public const T_VARIABLE = 319;
  18936. public const T_NUM_STRING = 320;
  18937. public const T_INLINE_HTML = 321;
  18938. public const T_ENCAPSED_AND_WHITESPACE = 322;
  18939. public const T_CONSTANT_ENCAPSED_STRING = 323;
  18940. public const T_ECHO = 324;
  18941. public const T_DO = 325;
  18942. public const T_WHILE = 326;
  18943. public const T_ENDWHILE = 327;
  18944. public const T_FOR = 328;
  18945. public const T_ENDFOR = 329;
  18946. public const T_FOREACH = 330;
  18947. public const T_ENDFOREACH = 331;
  18948. public const T_DECLARE = 332;
  18949. public const T_ENDDECLARE = 333;
  18950. public const T_AS = 334;
  18951. public const T_SWITCH = 335;
  18952. public const T_MATCH = 336;
  18953. public const T_ENDSWITCH = 337;
  18954. public const T_CASE = 338;
  18955. public const T_DEFAULT = 339;
  18956. public const T_BREAK = 340;
  18957. public const T_CONTINUE = 341;
  18958. public const T_GOTO = 342;
  18959. public const T_FUNCTION = 343;
  18960. public const T_FN = 344;
  18961. public const T_CONST = 345;
  18962. public const T_RETURN = 346;
  18963. public const T_TRY = 347;
  18964. public const T_CATCH = 348;
  18965. public const T_FINALLY = 349;
  18966. public const T_USE = 350;
  18967. public const T_INSTEADOF = 351;
  18968. public const T_GLOBAL = 352;
  18969. public const T_STATIC = 353;
  18970. public const T_ABSTRACT = 354;
  18971. public const T_FINAL = 355;
  18972. public const T_PRIVATE = 356;
  18973. public const T_PROTECTED = 357;
  18974. public const T_PUBLIC = 358;
  18975. public const T_READONLY = 359;
  18976. public const T_PUBLIC_SET = 360;
  18977. public const T_PROTECTED_SET = 361;
  18978. public const T_PRIVATE_SET = 362;
  18979. public const T_VAR = 363;
  18980. public const T_UNSET = 364;
  18981. public const T_ISSET = 365;
  18982. public const T_EMPTY = 366;
  18983. public const T_HALT_COMPILER = 367;
  18984. public const T_CLASS = 368;
  18985. public const T_TRAIT = 369;
  18986. public const T_INTERFACE = 370;
  18987. public const T_ENUM = 371;
  18988. public const T_EXTENDS = 372;
  18989. public const T_IMPLEMENTS = 373;
  18990. public const T_OBJECT_OPERATOR = 374;
  18991. public const T_NULLSAFE_OBJECT_OPERATOR = 375;
  18992. public const T_LIST = 376;
  18993. public const T_ARRAY = 377;
  18994. public const T_CALLABLE = 378;
  18995. public const T_CLASS_C = 379;
  18996. public const T_TRAIT_C = 380;
  18997. public const T_METHOD_C = 381;
  18998. public const T_FUNC_C = 382;
  18999. public const T_PROPERTY_C = 383;
  19000. public const T_LINE = 384;
  19001. public const T_FILE = 385;
  19002. public const T_START_HEREDOC = 386;
  19003. public const T_END_HEREDOC = 387;
  19004. public const T_DOLLAR_OPEN_CURLY_BRACES = 388;
  19005. public const T_CURLY_OPEN = 389;
  19006. public const T_PAAMAYIM_NEKUDOTAYIM = 390;
  19007. public const T_NAMESPACE = 391;
  19008. public const T_NS_C = 392;
  19009. public const T_DIR = 393;
  19010. public const T_NS_SEPARATOR = 394;
  19011. public const T_ELLIPSIS = 395;
  19012. public const T_NAME_FULLY_QUALIFIED = 396;
  19013. public const T_NAME_QUALIFIED = 397;
  19014. public const T_NAME_RELATIVE = 398;
  19015. public const T_ATTRIBUTE = 399;
  19016. protected int $tokenToSymbolMapSize = 400;
  19017. protected int $actionTableSize = 1289;
  19018. protected int $gotoTableSize = 608;
  19019. protected int $invalidSymbol = 172;
  19020. protected int $errorSymbol = 1;
  19021. protected int $defaultAction = -32766;
  19022. protected int $unexpectedTokenRule = 32767;
  19023. protected int $YY2TBLSTATE = 442;
  19024. protected int $numNonLeafStates = 753;
  19025. protected array $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "'.'", "T_SL", "T_SR", "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_PUBLIC_SET", "T_PROTECTED_SET", "T_PRIVATE_SET", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_PROPERTY_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'");
  19026. protected array $tokenToSymbol = array(0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 56, 170, 172, 171, 55, 172, 172, 165, 166, 53, 51, 8, 52, 48, 54, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 31, 163, 44, 16, 46, 30, 68, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 70, 172, 164, 36, 172, 169, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 167, 35, 168, 58, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 49, 50, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162);
  19027. protected array $action = array(126, 127, 128, 570, 129, 130, 955, 765, 766, 767, 131, 38, 849, -85, -32766, 1376, -32766, -32766, -32766, 0, 840, 1134, 1135, 1136, 1130, 1129, 1128, 1137, 1131, 1132, 1133, -32766, -32766, -32766, 851, 759, 758, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 1005, -32766, 1045, -570, 768, 1134, 1135, 1136, 1130, 1129, 1128, 1137, 1131, 1132, 1133, 388, 387, 842, 263, 132, 389, 772, 773, 774, 775, 430, 845, 431, -85, 2, 36, 246, 47, 291, 829, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 805, 571, 806, 807, 808, 809, 797, 798, 344, 345, 800, 801, 786, 787, 788, 790, 791, 792, 359, 832, 833, 834, 835, 836, 572, -570, -570, -332, 793, 794, 573, 574, 236, 817, 815, 816, 828, 812, 813, 26, -194, 575, 576, 811, 577, 578, 579, 580, 323, 581, 582, 876, 844, 877, 297, 298, 814, 583, 584, 722, 133, 846, 126, 127, 128, 570, 129, 130, 1078, 765, 766, 767, 131, 38, -32766, 35, 735, 1038, 1037, 1036, 1042, 1039, 1040, 1041, -32766, -32766, -32766, 1006, 104, 105, 106, 107, 108, -372, 275, -372, -32766, 759, 758, 1054, 850, -32766, -32766, -32766, 848, -32766, 109, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 134, 476, 477, 768, -32766, -32766, -32766, 1054, -32766, 290, -32766, -32766, -32766, -32766, -32766, 616, 143, 263, 132, 389, 772, 773, 774, 775, 249, -32766, 431, -32766, -32766, -32766, -32766, 290, 307, 829, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 805, 571, 806, 807, 808, 809, 797, 798, 344, 345, 800, 801, 786, 787, 788, 790, 791, 792, 359, 832, 833, 834, 835, 836, 572, 958, -273, -332, 793, 794, 573, 574, 840, 817, 815, 816, 828, 812, 813, 1301, -194, 575, 576, 811, 577, 578, 579, 580, 566, 581, 582, 1108, 82, 83, 84, 748, 814, 583, 584, 309, 146, 789, 760, 761, 762, 763, 764, 235, 765, 766, 767, 802, 803, 37, 957, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 157, 275, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 101, 102, 103, -32766, 109, 1313, 622, 318, 768, -32766, -32766, -32766, 849, 1361, -32766, 1107, -32766, -32766, -32766, 340, 1360, 1357, 769, 770, 771, 772, 773, 774, 775, 341, -32766, 838, -32766, -32766, 1386, 374, 1281, 1387, 829, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 805, 827, 806, 807, 808, 809, 797, 798, 799, 826, 800, 801, 786, 787, 788, 790, 791, 792, 831, 832, 833, 834, 835, 836, 837, 1077, 431, -567, 793, 794, 795, 796, 148, 817, 815, 816, 828, 812, 813, 380, -193, 804, 810, 811, 818, 819, 821, 820, 138, 822, 823, 840, 321, 396, 285, 24, 814, 825, 824, 49, 50, 51, 522, 52, 53, 398, -110, 7, 849, 54, 55, -110, 56, -110, -32766, -32766, -32766, 1342, 303, 125, 1123, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 161, 750, -567, -567, 291, 974, 975, -32766, -32766, -32766, 976, 448, 285, 1276, 1275, 1277, 57, 58, -567, -32766, -32766, 59, 1109, 60, 243, 244, 61, 62, 63, 64, 65, 66, 67, 68, -32766, 28, 265, 69, 446, 523, 490, -346, 449, 1307, 1308, 524, 139, 849, 1051, 450, 321, 1305, 42, 20, 525, 934, 526, 934, 527, 74, 528, -568, 698, 529, 530, 321, 386, 387, 44, 45, 452, 383, 382, 1054, 46, 531, 430, 974, 975, 451, 372, 339, 976, 1281, 855, 725, 934, 1267, 759, 758, -32766, 970, 533, 534, 535, 149, 934, 281, 699, -78, -566, 1274, 102, 103, 537, 538, -193, 1293, 1294, 1295, 1296, 1298, 1290, 1291, 295, 1054, 726, 466, 467, 468, 1297, 1292, 700, 701, 1276, 1275, 1277, 296, -568, -568, 70, -153, -153, -153, 316, 317, 321, 1272, 924, 290, 924, 1276, 1275, 1277, -568, 1051, -153, 281, -153, 1150, -153, 81, -153, 740, 151, 321, -574, 152, 759, 758, -32766, 1053, 381, 876, 849, 877, 153, -566, -566, 924, 1054, 1051, 155, 974, 975, -606, 491, -606, 532, 924, 1276, 1275, 1277, -566, 33, 1054, 910, 970, -110, -110, -110, 28, 266, -58, 281, -573, 1054, -32766, -32766, -110, -110, 665, 21, 849, -110, -57, -564, 1305, 684, 685, 147, 413, 123, -110, 384, 385, 124, 936, 135, 936, 136, 720, -32766, 720, -153, 142, 48, 32, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 390, 391, 1267, 296, 759, 758, 74, 936, 156, 934, 158, 720, 321, -4, 934, 159, 934, 936, 160, 537, 538, 720, 1293, 1294, 1295, 1296, 1298, 1290, 1291, 1183, 1185, 934, -564, -564, -565, 1297, 1292, 759, 758, 727, -564, -32766, 656, 657, -306, 72, 730, 1274, -564, -87, 317, 321, 299, 300, -32766, -32766, -32766, -84, -32766, -78, -32766, 737, -32766, -73, -72, -32766, -71, -70, 379, -69, -32766, -32766, -32766, -68, -32766, -67, -32766, -32766, -66, -65, 1274, -46, -32766, 427, 28, 265, -18, -32766, -32766, -32766, 140, -32766, 924, -32766, -32766, -32766, 849, 924, -32766, 924, 1305, -565, -565, -32766, -32766, -32766, 274, -564, -564, -32766, -32766, 282, 736, 739, 924, -32766, 427, -565, 933, 381, 145, 443, 286, -564, 951, 73, 294, -32766, -302, -572, 974, 975, 279, 280, 283, 532, 1267, 28, 266, 284, 329, 275, 109, 536, 970, -110, -110, -110, 287, 849, 292, 293, 840, 1305, 538, 694, 1293, 1294, 1295, 1296, 1298, 1290, 1291, 709, 144, 587, 711, 11, 10, 1297, 1292, 991, 849, 1141, 473, 720, 936, -32766, 936, 72, 720, -4, 720, 1388, 317, 321, -50, 970, 672, 1267, 687, 666, 501, 936, 971, 301, 308, 720, 671, 1312, 302, 1314, -32766, 688, 953, -530, -520, 538, 40, 1293, 1294, 1295, 1296, 1298, 1290, 1291, 848, 41, 8, 137, 654, 27, 1297, 1292, 304, 34, 593, 620, 296, -32766, 0, 0, 72, 0, 0, 1274, 0, 317, 321, 0, 0, 0, -32766, -32766, -32766, -276, -32766, 0, -32766, 0, -32766, 0, 0, -32766, 0, 0, 0, 0, -32766, -32766, -32766, 934, -32766, 0, -32766, -32766, 0, 0, 1274, 378, -32766, 427, 745, -600, 412, -32766, -32766, -32766, 746, -32766, 868, -32766, -32766, -32766, 934, 915, -32766, 1015, 992, 999, 989, -32766, -32766, -32766, 1000, -32766, 913, -32766, -32766, 987, 1112, 1274, 1115, -32766, 427, 1116, 1113, 1152, -32766, -32766, -32766, 1114, -32766, 1120, -32766, -32766, -32766, 1302, 860, -32766, 1329, 1346, 1379, 496, -32766, -32766, -32766, 659, -32766, -599, -32766, -32766, -598, -574, 1274, 600, -32766, 427, -573, -572, -571, -32766, -32766, -32766, 924, -32766, -514, -32766, -32766, -32766, 1, 29, -32766, -274, 30, 39, 43, -32766, -32766, -32766, -251, -251, -251, -32766, -32766, 71, 381, 924, 75, -32766, 427, 76, 77, 78, 1281, 79, 80, 974, 975, 141, 150, -32766, 532, -250, -250, -250, -273, 154, 241, 381, 910, 970, -110, -110, -110, 325, 360, 361, 362, 363, 974, 975, 364, 365, -16, 532, 366, 367, 368, 369, 370, 373, 444, 910, 970, -110, -110, -110, -32766, 13, 565, 371, 1306, 936, 1274, 14, 416, 720, -251, 15, 16, -32766, -32766, -32766, 18, -32766, 354, -32766, 411, -32766, 492, 493, -32766, 500, 503, 504, 936, -32766, -32766, -32766, 720, -250, 505, -32766, -32766, 849, 506, 510, 511, -32766, 427, 512, 519, 598, 704, 1080, 1223, 1303, 1079, 1060, 1262, -32766, 1056, -278, -102, 12, 17, 22, 312, 410, 612, 617, 645, 710, 1227, 1280, 1224, 1358, 0, 315, -110, -110, 375, 721, 724, -110, 728, 729, 731, 732, 733, 734, 738, 750, -110, 723, 751, 0, 742, 911, 1383, 1385, 0, -32766, 871, 870, 964, 1007, 1384, 963, 961, 962, 965, 1255, 944, 954, 942, 1151, 1147, 1101, 997, 998, 643, 1382, 1340, 296, 1355, 0, 74, 1240, 321, 0, 0, 0, 321);
  19028. protected array $actionCheck = array(2, 3, 4, 5, 6, 7, 1, 9, 10, 11, 12, 13, 82, 31, 116, 85, 9, 10, 11, 0, 80, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 9, 10, 11, 1, 37, 38, 30, 140, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 31, 30, 1, 70, 57, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 106, 107, 80, 71, 72, 73, 74, 75, 76, 77, 116, 80, 80, 97, 8, 151, 152, 70, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 137, 138, 8, 126, 127, 128, 129, 14, 131, 132, 133, 134, 135, 136, 8, 8, 139, 140, 141, 142, 143, 144, 145, 70, 147, 148, 106, 160, 108, 137, 138, 154, 155, 156, 167, 158, 160, 2, 3, 4, 5, 6, 7, 166, 9, 10, 11, 12, 13, 116, 8, 167, 119, 120, 121, 122, 123, 124, 125, 9, 10, 11, 163, 51, 52, 53, 54, 55, 106, 57, 108, 116, 37, 38, 141, 163, 9, 10, 11, 159, 30, 69, 32, 33, 34, 35, 36, 37, 38, 8, 137, 138, 57, 9, 10, 11, 141, 30, 165, 32, 33, 34, 35, 36, 1, 8, 71, 72, 73, 74, 75, 76, 77, 8, 30, 80, 32, 33, 34, 35, 165, 8, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 73, 166, 166, 126, 127, 128, 129, 80, 131, 132, 133, 134, 135, 136, 1, 166, 139, 140, 141, 142, 143, 144, 145, 85, 147, 148, 163, 9, 10, 11, 167, 154, 155, 156, 8, 158, 2, 3, 4, 5, 6, 7, 97, 9, 10, 11, 12, 13, 30, 122, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 16, 57, 9, 10, 11, 44, 45, 46, 47, 48, 49, 50, 9, 69, 150, 52, 8, 57, 9, 10, 11, 82, 1, 30, 1, 32, 33, 34, 8, 8, 1, 71, 72, 73, 74, 75, 76, 77, 8, 30, 80, 32, 33, 80, 8, 1, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 1, 80, 70, 126, 127, 128, 129, 14, 131, 132, 133, 134, 135, 136, 8, 8, 139, 140, 141, 142, 143, 144, 145, 167, 147, 148, 80, 171, 8, 30, 101, 154, 155, 156, 2, 3, 4, 5, 6, 7, 106, 101, 108, 82, 12, 13, 106, 15, 108, 9, 10, 11, 1, 113, 14, 126, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 14, 167, 137, 138, 30, 117, 118, 9, 10, 11, 122, 8, 30, 159, 160, 161, 51, 52, 153, 9, 10, 56, 168, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 140, 70, 71, 72, 73, 74, 31, 168, 8, 78, 79, 80, 167, 82, 116, 8, 171, 86, 87, 88, 89, 1, 91, 1, 93, 165, 95, 70, 80, 98, 99, 171, 106, 107, 103, 104, 105, 106, 107, 141, 109, 110, 116, 117, 118, 8, 115, 116, 122, 1, 8, 31, 1, 122, 37, 38, 116, 131, 127, 128, 129, 14, 1, 165, 116, 16, 70, 80, 49, 50, 139, 140, 166, 142, 143, 144, 145, 146, 147, 148, 149, 141, 31, 132, 133, 134, 155, 156, 140, 141, 159, 160, 161, 162, 137, 138, 165, 75, 76, 77, 169, 170, 171, 116, 84, 165, 84, 159, 160, 161, 153, 116, 90, 165, 92, 163, 94, 167, 96, 167, 14, 171, 165, 14, 37, 38, 116, 140, 106, 106, 82, 108, 14, 137, 138, 84, 141, 116, 14, 117, 118, 164, 167, 166, 122, 84, 159, 160, 161, 153, 14, 141, 130, 131, 132, 133, 134, 70, 71, 16, 165, 165, 141, 51, 52, 117, 118, 75, 76, 82, 122, 16, 70, 86, 75, 76, 101, 102, 16, 131, 106, 107, 16, 163, 16, 163, 16, 167, 140, 167, 168, 16, 70, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 106, 107, 122, 162, 37, 38, 165, 163, 16, 1, 16, 167, 171, 0, 1, 16, 1, 163, 16, 139, 140, 167, 142, 143, 144, 145, 146, 147, 148, 59, 60, 1, 137, 138, 70, 155, 156, 37, 38, 31, 70, 74, 111, 112, 35, 165, 31, 80, 153, 31, 170, 171, 137, 138, 87, 88, 89, 31, 91, 31, 93, 31, 95, 31, 31, 98, 31, 31, 153, 31, 103, 104, 105, 31, 74, 31, 109, 110, 31, 31, 80, 31, 115, 116, 70, 71, 31, 87, 88, 89, 31, 91, 84, 93, 127, 95, 82, 84, 98, 84, 86, 137, 138, 103, 104, 105, 31, 137, 138, 109, 110, 31, 31, 31, 84, 115, 116, 153, 31, 106, 31, 108, 37, 153, 38, 158, 113, 127, 35, 165, 117, 118, 35, 35, 35, 122, 122, 70, 71, 35, 35, 57, 69, 130, 131, 132, 133, 134, 37, 82, 37, 37, 80, 86, 140, 77, 142, 143, 144, 145, 146, 147, 148, 80, 70, 89, 92, 154, 97, 155, 156, 163, 82, 82, 97, 167, 163, 85, 163, 165, 167, 168, 167, 83, 170, 171, 31, 131, 100, 122, 94, 90, 97, 163, 131, 135, 135, 167, 96, 150, 136, 150, 140, 100, 158, 153, 153, 140, 163, 142, 143, 144, 145, 146, 147, 148, 159, 163, 153, 31, 113, 153, 155, 156, 114, 167, 157, 157, 162, 74, -1, -1, 165, -1, -1, 80, -1, 170, 171, -1, -1, -1, 87, 88, 89, 166, 91, -1, 93, -1, 95, -1, -1, 98, -1, -1, -1, -1, 103, 104, 105, 1, 74, -1, 109, 110, -1, -1, 80, 153, 115, 116, 163, 165, 168, 87, 88, 89, 163, 91, 163, 93, 127, 95, 1, 163, 98, 163, 163, 163, 163, 103, 104, 105, 163, 74, 163, 109, 110, 163, 163, 80, 163, 115, 116, 163, 163, 163, 87, 88, 89, 163, 91, 163, 93, 127, 95, 164, 164, 98, 164, 164, 164, 102, 103, 104, 105, 164, 74, 165, 109, 110, 165, 165, 80, 81, 115, 116, 165, 165, 165, 87, 88, 89, 84, 91, 165, 93, 127, 95, 165, 165, 98, 166, 165, 165, 165, 103, 104, 105, 100, 101, 102, 109, 110, 165, 106, 84, 165, 115, 116, 165, 165, 165, 1, 165, 165, 117, 118, 165, 165, 127, 122, 100, 101, 102, 166, 165, 165, 106, 130, 131, 132, 133, 134, 165, 165, 165, 165, 165, 117, 118, 165, 165, 31, 122, 165, 165, 165, 165, 165, 165, 165, 130, 131, 132, 133, 134, 74, 166, 165, 165, 170, 163, 80, 166, 168, 167, 168, 166, 166, 87, 88, 89, 166, 91, 166, 93, 166, 95, 166, 166, 98, 166, 166, 166, 163, 103, 104, 105, 167, 168, 166, 109, 110, 82, 166, 166, 166, 115, 116, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 127, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -1, 167, 117, 118, 167, 167, 167, 122, 167, 167, 167, 167, 167, 167, 167, 167, 131, 167, 167, -1, 168, 168, 168, 168, -1, 140, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 162, 168, -1, 165, 169, 171, -1, -1, -1, 171);
  19029. protected array $actionBase = array(0, -2, 156, 559, 757, 1004, 1027, 485, 292, 357, -60, -12, 588, 759, 759, 774, 759, 557, 752, 892, 598, 598, 598, 827, 313, 313, 827, 313, 711, 711, 711, 711, 744, 744, 965, 965, 998, 932, 899, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 33, 20, 224, 1080, 673, 1056, 1062, 1058, 1063, 1054, 1053, 1057, 1059, 1064, 1109, 1110, 833, 1108, 1112, 1060, 907, 1055, 1061, 888, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 356, 476, 513, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 624, 624, 22, 22, 22, 362, 811, 758, 811, 811, 811, 811, 811, 811, 811, 811, 346, 205, 188, 714, 171, 171, 7, 7, 7, 7, 7, 376, 1117, 54, 585, 585, 314, 314, 314, 314, 365, 554, 83, 435, 397, 556, 477, 463, 532, 532, 558, 558, 76, 76, 558, 558, 558, 133, 133, 547, 547, 547, 547, 41, 217, 806, 382, 382, 382, 382, 806, 806, 806, 806, 795, 996, 806, 806, 806, 494, 533, 708, 649, 649, 560, -70, -70, 560, 800, -70, 487, 975, 316, 982, -102, 807, -40, 514, -102, 1000, 368, 639, 639, 659, 639, 639, 639, 801, 611, 801, 1052, 836, 836, 794, 776, 894, 1082, 1065, 832, 1106, 847, 1107, 1083, 489, 488, -16, 13, 74, 772, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1113, 554, 1052, -3, 1104, 1105, 1113, 1113, 1113, 554, 554, 554, 554, 554, 554, 554, 554, 799, 554, 554, 675, -3, 629, 636, -3, 849, 554, 797, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 512, 33, 33, 20, 5, 5, 33, 142, 52, 5, 5, 5, 337, 5, 33, 33, 33, 611, 828, 813, 638, -18, 814, 443, 828, 828, 828, 115, 114, 128, 753, 837, 370, 816, 816, 835, 929, 929, 816, 834, 816, 835, 816, 816, 929, 929, 810, 929, 202, 506, 373, 442, 537, 929, 234, 816, 816, 816, 816, 805, 929, 72, 544, 816, 226, 218, 816, 816, 805, 804, 824, 808, 929, 929, 929, 805, 389, 808, 808, 808, 853, 859, 851, 819, 361, 305, 579, 163, 830, 819, 819, 816, 456, 851, 819, 851, 819, 790, 819, 819, 819, 851, 819, 834, 383, 819, 736, 574, 127, 819, 816, 19, 944, 947, 762, 950, 934, 951, 991, 952, 954, 1070, 925, 967, 935, 955, 999, 933, 930, 831, 699, 703, 809, 796, 919, 817, 817, 817, 912, 917, 817, 817, 817, 817, 817, 817, 817, 817, 699, 897, 860, 820, 976, 705, 707, 1041, 793, 1085, 1114, 975, 944, 954, 770, 935, 955, 933, 930, 792, 791, 786, 788, 782, 780, 777, 779, 803, 1043, 958, 789, 712, 1012, 977, 1084, 1066, 978, 981, 1016, 1044, 861, 1045, 1086, 838, 1087, 1090, 898, 985, 1071, 817, 911, 852, 900, 982, 918, 699, 901, 1046, 997, 802, 1018, 1019, 1069, 821, 844, 902, 1091, 986, 987, 988, 1073, 1074, 798, 1003, 823, 1021, 839, 850, 1022, 1023, 1030, 1034, 1075, 1092, 1076, 908, 1077, 866, 845, 931, 846, 1093, 429, 843, 848, 858, 990, 584, 974, 1078, 1002, 1094, 1035, 1036, 1039, 1095, 1096, 959, 868, 1007, 840, 1008, 964, 869, 870, 643, 857, 1047, 841, 842, 855, 646, 655, 1097, 1098, 1099, 966, 825, 822, 871, 875, 1048, 829, 1050, 1100, 661, 877, 1101, 1042, 738, 743, 586, 692, 680, 746, 818, 1079, 812, 854, 815, 989, 743, 826, 880, 1102, 881, 883, 886, 1040, 887, 1014, 1103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, 468, 468, 468, 468, 468, 313, 313, 313, 313, 313, 468, 468, 468, 468, 468, 468, 468, 313, 468, 468, 468, 313, 0, 0, 313, 0, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 524, 524, 297, 297, 297, 297, 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 297, 297, 297, 0, 297, 297, 297, 297, 297, 297, 297, 810, 524, 524, 524, 524, 133, 133, 133, 133, -95, -95, -95, 524, 524, 133, 524, 810, 524, 524, 524, 524, 524, 524, 524, 524, 524, 0, 0, 524, 524, 524, 524, -3, -70, 524, 834, 834, 834, 834, 524, 524, 524, 524, -70, -70, 524, 524, 524, 0, 0, 0, 133, 133, -3, 0, 0, -3, 391, 0, 834, 206, 834, 206, 524, 391, 810, 374, 524, 489, 0, 0, 0, 0, 0, 0, 0, -3, 834, -3, 554, -70, -70, 554, 554, 5, 33, 374, 612, 612, 612, 612, 33, 0, 0, 0, 0, 0, 611, 810, 810, 810, 810, 810, 810, 810, 810, 810, 810, 810, 810, 834, 0, 810, 0, 810, 810, 834, 834, 834, 0, 0, 0, 0, 0, 0, 0, 0, 929, 0, 0, 0, 0, 0, 0, 0, 834, 0, 929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 817, 821, 0, 0, 821, 0, 817, 817, 817, 0, 0, 0, 857, 829);
  19030. protected array $actionDefault = array(3, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 618, 618, 618, 618, 32767, 32767, 255, 102, 32767, 32767, 489, 406, 406, 406, 32767, 32767, 562, 562, 562, 562, 562, 32767, 32767, 32767, 32767, 32767, 32767, 489, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 36, 7, 8, 10, 11, 49, 17, 328, 100, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 393, 611, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 493, 472, 473, 475, 476, 405, 563, 617, 331, 614, 333, 404, 145, 343, 334, 243, 259, 494, 260, 495, 498, 499, 216, 390, 149, 150, 436, 490, 438, 488, 492, 437, 411, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 409, 410, 491, 32767, 32767, 469, 468, 467, 434, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 435, 439, 442, 408, 440, 441, 458, 459, 456, 457, 460, 32767, 32767, 320, 32767, 32767, 461, 462, 463, 464, 371, 195, 369, 32767, 32767, 443, 320, 111, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 449, 450, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 100, 506, 556, 466, 444, 445, 32767, 531, 32767, 102, 32767, 533, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 558, 431, 433, 526, 612, 412, 615, 32767, 519, 100, 195, 32767, 532, 195, 195, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 557, 32767, 625, 519, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 195, 110, 32767, 110, 110, 32767, 32767, 100, 195, 195, 195, 195, 195, 195, 195, 195, 534, 195, 195, 190, 32767, 269, 271, 102, 580, 195, 536, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 393, 32767, 32767, 32767, 32767, 519, 454, 138, 32767, 521, 138, 564, 446, 447, 448, 564, 564, 564, 316, 293, 32767, 32767, 32767, 32767, 534, 534, 100, 100, 100, 100, 32767, 32767, 32767, 32767, 111, 505, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 224, 32767, 101, 99, 32767, 101, 101, 32767, 32767, 224, 226, 213, 228, 32767, 584, 585, 224, 101, 228, 228, 228, 248, 248, 508, 322, 101, 99, 101, 101, 197, 322, 322, 32767, 101, 508, 322, 508, 322, 199, 322, 322, 322, 508, 322, 32767, 101, 322, 215, 99, 99, 322, 32767, 32767, 32767, 32767, 521, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 223, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 551, 32767, 569, 582, 452, 453, 455, 568, 566, 477, 478, 479, 480, 481, 482, 483, 485, 613, 32767, 525, 32767, 32767, 32767, 342, 32767, 623, 32767, 32767, 32767, 9, 74, 514, 42, 43, 51, 57, 540, 541, 542, 543, 537, 538, 544, 539, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 624, 32767, 564, 32767, 32767, 32767, 32767, 451, 546, 590, 32767, 32767, 565, 616, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 138, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 551, 32767, 136, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 547, 32767, 32767, 32767, 564, 32767, 32767, 32767, 32767, 318, 315, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 564, 32767, 32767, 32767, 32767, 32767, 295, 32767, 312, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 389, 521, 298, 300, 301, 32767, 32767, 32767, 32767, 365, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 345, 152, 152, 152, 345, 345, 152, 345, 345, 345, 152, 152, 152, 152, 152, 152, 152, 281, 185, 263, 266, 248, 248, 152, 357, 152, 391, 391, 400);
  19031. protected array $goto = array(194, 194, 1052, 487, 705, 278, 278, 278, 278, 990, 489, 548, 548, 907, 865, 907, 907, 548, 714, 548, 548, 548, 548, 548, 548, 548, 548, 166, 166, 166, 166, 218, 195, 191, 191, 176, 178, 213, 191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 186, 187, 188, 189, 190, 215, 213, 216, 545, 546, 428, 547, 550, 551, 552, 553, 554, 555, 556, 557, 1169, 167, 168, 169, 193, 170, 171, 172, 164, 173, 174, 175, 177, 212, 214, 217, 237, 240, 251, 252, 253, 255, 256, 257, 258, 259, 260, 261, 267, 268, 269, 270, 276, 288, 289, 313, 314, 434, 435, 436, 607, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 186, 187, 188, 189, 190, 215, 1169, 196, 197, 198, 199, 238, 179, 180, 200, 181, 201, 197, 182, 239, 196, 163, 202, 203, 183, 204, 205, 206, 184, 207, 208, 165, 209, 210, 211, 185, 869, 560, 1083, 560, 560, 592, 1100, 475, 475, 744, 646, 648, 609, 560, 668, 432, 475, 621, 692, 695, 1025, 703, 712, 1021, 719, 558, 558, 558, 558, 470, 613, 866, 663, 664, 463, 681, 682, 683, 1218, 984, 984, 984, 984, 247, 247, 463, 978, 985, 355, 355, 355, 355, 867, 923, 918, 919, 932, 875, 920, 872, 921, 922, 873, 350, 926, 879, 1126, 1154, 1127, 878, 245, 245, 245, 245, 242, 248, 841, 1106, 1102, 1103, 438, 670, 402, 405, 610, 614, 433, 336, 332, 333, 335, 602, 437, 337, 439, 647, 426, 1273, 1052, 1273, 1273, 342, 900, 456, 456, 348, 456, 456, 1052, 1273, 882, 1052, 520, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 343, 342, 1052, 1052, 1052, 1052, 894, 465, 1273, 881, 508, 599, 509, 1273, 1273, 1273, 1273, 358, 515, 1273, 1273, 1273, 1354, 1354, 1354, 1354, 862, 358, 358, 1372, 1372, 630, 667, 895, 883, 1088, 1092, 940, 358, 358, 1362, 941, 358, 1011, 1372, 1389, 993, 956, 447, 956, 619, 633, 636, 637, 638, 639, 660, 661, 662, 716, 718, 564, 569, 562, 358, 358, 1375, 1375, 400, 983, 1055, 1055, 690, 967, 597, 862, 1047, 1063, 1064, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 1138, 899, 456, 669, 456, 456, 1058, 1057, 322, 562, 569, 594, 595, 324, 605, 611, 1166, 626, 627, 1028, 1028, 1061, 1062, 632, 632, 25, 320, 306, 1334, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 702, 1349, 1350, 1014, 843, 5, 986, 6, 743, 445, 422, 561, 1023, 1018, 1076, 1345, 702, 1345, 1345, 702, 603, 624, 1323, 1323, 691, 250, 250, 1345, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 563, 589, 927, 564, 928, 563, 675, 589, 859, 403, 469, 1356, 1356, 1356, 1356, 338, 887, 271, 319, 625, 319, 319, 478, 606, 479, 480, 973, 351, 352, 409, 892, 1320, 1320, 1380, 1381, 1341, 862, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 982, 417, 713, 1268, 1264, 414, 415, 1033, 884, 440, 679, 890, 680, 1149, 419, 420, 421, 1089, 693, 847, 1266, 423, 440, 747, 1043, 346, 485, 1093, 1059, 1059, 330, 484, 1347, 1348, 1140, 674, 1070, 1066, 1067, 1091, 896, 995, 549, 549, 377, 1343, 1343, 1091, 549, 549, 549, 549, 549, 549, 549, 549, 549, 549, 1269, 1270, 0, 1256, 0, 847, 0, 847, 615, 857, 0, 945, 1156, 640, 642, 644, 1256, 0, 0, 0, 0, 608, 1119, 1030, 0, 0, 752, 752, 1271, 1331, 1332, 886, 717, 673, 1009, 0, 0, 516, 708, 880, 1117, 1249, 959, 0, 0, 0, 1250, 1253, 960, 0, 1254, 1263);
  19032. protected array $gotoCheck = array(42, 42, 73, 84, 73, 23, 23, 23, 23, 49, 84, 162, 162, 25, 25, 25, 25, 162, 9, 162, 162, 162, 162, 162, 162, 162, 162, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 15, 19, 128, 19, 19, 48, 15, 154, 154, 48, 48, 48, 131, 19, 48, 13, 154, 13, 48, 48, 48, 48, 48, 48, 48, 107, 107, 107, 107, 156, 107, 26, 86, 86, 19, 86, 86, 86, 156, 19, 19, 19, 19, 5, 5, 19, 19, 19, 24, 24, 24, 24, 27, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 97, 15, 15, 146, 146, 146, 15, 5, 5, 5, 5, 5, 5, 6, 15, 15, 15, 66, 66, 59, 59, 59, 59, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 43, 73, 73, 73, 73, 174, 45, 23, 23, 185, 23, 23, 73, 73, 35, 73, 76, 73, 73, 73, 73, 73, 73, 73, 73, 73, 174, 174, 73, 73, 73, 73, 35, 83, 73, 35, 160, 178, 160, 73, 73, 73, 73, 14, 160, 73, 73, 73, 9, 9, 9, 9, 22, 14, 14, 188, 188, 56, 56, 16, 16, 16, 16, 73, 14, 14, 187, 73, 14, 103, 188, 14, 16, 9, 83, 9, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 14, 76, 76, 14, 14, 188, 188, 62, 16, 89, 89, 89, 89, 104, 22, 89, 89, 89, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 16, 23, 64, 23, 23, 119, 119, 76, 76, 76, 76, 76, 76, 76, 76, 155, 76, 76, 107, 107, 120, 120, 108, 108, 76, 175, 175, 14, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 7, 184, 184, 50, 7, 46, 50, 46, 50, 113, 14, 50, 50, 50, 115, 131, 7, 131, 131, 7, 2, 2, 176, 176, 117, 5, 5, 131, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 9, 9, 65, 14, 65, 9, 121, 9, 18, 9, 9, 131, 131, 131, 131, 29, 39, 24, 24, 80, 24, 24, 9, 9, 9, 9, 92, 97, 97, 28, 9, 177, 177, 9, 9, 131, 22, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 93, 93, 93, 20, 166, 82, 82, 110, 37, 118, 82, 9, 82, 153, 82, 82, 82, 130, 82, 12, 14, 82, 118, 99, 114, 82, 157, 133, 118, 118, 9, 182, 182, 182, 149, 118, 118, 118, 118, 131, 41, 96, 179, 179, 138, 131, 131, 131, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 20, 20, -1, 20, -1, 12, -1, 12, 17, 20, -1, 17, 17, 85, 85, 85, 20, -1, -1, -1, -1, 8, 8, 17, -1, -1, 24, 24, 20, 20, 20, 17, 8, 17, 17, -1, -1, 8, 8, 17, 8, 79, 79, -1, -1, -1, 79, 79, 79, -1, 79, 17);
  19033. protected array $gotoBase = array(0, 0, -289, 0, 0, 203, 227, 406, 569, 8, 0, 0, 223, -162, 5, -186, -143, 93, 152, -101, 102, 0, 31, 2, 206, 10, 188, 209, 142, 172, 0, 0, 0, 0, 0, -104, 0, 166, 0, 149, 0, 90, -1, 234, 0, 237, -329, 0, -555, -9, 404, 0, 0, 0, 0, 0, 274, 0, 0, 198, 0, 0, 309, 0, 141, 439, 6, 0, 0, 0, 0, 0, 0, -5, 0, 0, 1, 0, 0, 183, 146, -28, 4, 12, -475, 82, -535, 0, 0, 74, 0, 0, 151, 196, 0, 0, 89, -267, 0, 108, 0, 0, 0, 291, 314, 0, 0, 158, 162, 0, 131, 0, 0, 145, 100, 153, 0, 156, 243, 101, 112, 167, 0, 0, 0, 0, 0, 0, 161, 0, 135, 165, 0, 76, 0, 0, 0, 0, -209, 0, 0, 0, 0, 0, 0, 0, -44, 0, 0, 81, 0, 0, 0, 157, 134, 148, -76, 77, 0, 0, -210, 0, -224, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, -33, 84, 200, 247, 265, 305, 0, 0, 231, 0, 36, 236, 0, 292, 7, 0, 0);
  19034. protected array $gotoDefault = array(-32768, 521, 754, 4, 755, 949, 830, 839, 585, 539, 715, 347, 634, 429, 1339, 925, 1155, 604, 858, 1282, 1288, 464, 861, 327, 741, 937, 908, 909, 406, 393, 874, 404, 658, 635, 502, 893, 460, 885, 494, 888, 459, 897, 162, 425, 518, 901, 3, 904, 567, 935, 988, 394, 912, 395, 686, 914, 588, 916, 917, 401, 407, 408, 1160, 596, 631, 929, 254, 590, 930, 392, 931, 939, 397, 399, 696, 474, 513, 507, 418, 1121, 591, 618, 655, 453, 481, 629, 641, 628, 488, 441, 424, 326, 972, 980, 495, 472, 994, 349, 1002, 749, 1168, 649, 497, 1010, 650, 1017, 1020, 540, 541, 486, 1032, 264, 1035, 498, 1044, 23, 676, 1049, 1050, 677, 651, 1072, 652, 678, 653, 1074, 471, 586, 1082, 461, 1090, 1328, 462, 1094, 262, 1097, 277, 353, 376, 442, 1104, 1105, 9, 1111, 706, 707, 19, 273, 517, 1139, 697, 1145, 272, 1148, 458, 1167, 457, 1237, 1239, 568, 499, 1257, 310, 1260, 689, 514, 1265, 454, 1330, 455, 542, 482, 334, 543, 1373, 305, 356, 331, 559, 311, 357, 544, 483, 1336, 1344, 328, 31, 1363, 1374, 601, 623);
  19035. protected array $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 80, 26, 26, 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, 81, 109, 109, 111, 111, 112, 112, 112, 112, 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, 20, 127, 126, 126, 128, 128, 128, 128, 60, 129, 129, 130, 61, 132, 132, 133, 133, 134, 134, 86, 135, 135, 135, 135, 135, 135, 135, 135, 141, 141, 142, 142, 143, 143, 143, 143, 143, 144, 145, 145, 140, 140, 136, 136, 139, 139, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 137, 148, 148, 150, 149, 149, 138, 138, 114, 114, 151, 151, 153, 153, 153, 152, 152, 62, 104, 154, 154, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 161, 162, 162, 163, 155, 155, 160, 160, 164, 165, 165, 166, 167, 168, 168, 168, 168, 19, 19, 73, 73, 73, 73, 156, 156, 156, 156, 170, 170, 159, 159, 159, 157, 157, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, 177, 108, 179, 179, 179, 179, 158, 158, 158, 158, 158, 158, 158, 158, 59, 59, 173, 173, 173, 173, 173, 180, 180, 169, 169, 169, 169, 181, 181, 181, 181, 181, 74, 74, 66, 66, 66, 66, 131, 131, 131, 131, 184, 183, 172, 172, 172, 172, 172, 172, 171, 171, 171, 182, 182, 182, 182, 107, 178, 186, 186, 185, 185, 187, 187, 187, 187, 187, 187, 187, 187, 175, 175, 175, 175, 174, 189, 188, 188, 188, 188, 188, 188, 188, 188, 190, 190, 190, 190);
  19036. protected array $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, 4, 1, 3, 1, 1, 8, 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 1, 1, 1, 7, 9, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 7, 5, 6, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 0, 2, 0, 3, 5, 8, 1, 3, 3, 0, 2, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 2, 1, 1, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1);
  19037. protected function initReduceCallbacks(): void
  19038. {
  19039. $this->reduceCallbacks = [0 => null, 1 => static function ($self, $stackPos) {
  19040. $self->semValue = $self->handleNamespaces($self->semStack[$stackPos - (1 - 1)]);
  19041. }, 2 => static function ($self, $stackPos) {
  19042. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  19043. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19044. }
  19045. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19046. }, 3 => static function ($self, $stackPos) {
  19047. $self->semValue = array();
  19048. }, 4 => static function ($self, $stackPos) {
  19049. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  19050. if ($nop !== null) {
  19051. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  19052. }
  19053. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19054. }, 5 => null, 6 => null, 7 => null, 8 => null, 9 => null, 10 => null, 11 => null, 12 => null, 13 => null, 14 => null, 15 => null, 16 => null, 17 => null, 18 => null, 19 => null, 20 => null, 21 => null, 22 => null, 23 => null, 24 => null, 25 => null, 26 => null, 27 => null, 28 => null, 29 => null, 30 => null, 31 => null, 32 => null, 33 => null, 34 => null, 35 => null, 36 => null, 37 => null, 38 => null, 39 => null, 40 => null, 41 => null, 42 => null, 43 => null, 44 => null, 45 => null, 46 => null, 47 => null, 48 => null, 49 => null, 50 => null, 51 => null, 52 => null, 53 => null, 54 => null, 55 => null, 56 => null, 57 => null, 58 => null, 59 => null, 60 => null, 61 => null, 62 => null, 63 => null, 64 => null, 65 => null, 66 => null, 67 => null, 68 => null, 69 => null, 70 => null, 71 => null, 72 => null, 73 => null, 74 => null, 75 => null, 76 => static function ($self, $stackPos) {
  19055. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19056. if ($self->semValue === "<?=") {
  19057. $self->emitError(new Error('Cannot use "<?=" as an identifier', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
  19058. }
  19059. }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => static function ($self, $stackPos) {
  19060. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19061. }, 86 => static function ($self, $stackPos) {
  19062. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19063. }, 87 => static function ($self, $stackPos) {
  19064. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19065. }, 88 => static function ($self, $stackPos) {
  19066. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19067. }, 89 => static function ($self, $stackPos) {
  19068. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19069. }, 90 => static function ($self, $stackPos) {
  19070. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19071. }, 91 => static function ($self, $stackPos) {
  19072. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19073. }, 92 => static function ($self, $stackPos) {
  19074. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19075. }, 93 => static function ($self, $stackPos) {
  19076. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19077. }, 94 => null, 95 => static function ($self, $stackPos) {
  19078. $self->semValue = new Name(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19079. }, 96 => static function ($self, $stackPos) {
  19080. $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19081. }, 97 => static function ($self, $stackPos) {
  19082. /* nothing */
  19083. }, 98 => static function ($self, $stackPos) {
  19084. /* nothing */
  19085. }, 99 => static function ($self, $stackPos) {
  19086. /* nothing */
  19087. }, 100 => static function ($self, $stackPos) {
  19088. $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
  19089. }, 101 => null, 102 => null, 103 => static function ($self, $stackPos) {
  19090. $self->semValue = new Node\Attribute($self->semStack[$stackPos - (1 - 1)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19091. }, 104 => static function ($self, $stackPos) {
  19092. $self->semValue = new Node\Attribute($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19093. }, 105 => static function ($self, $stackPos) {
  19094. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19095. }, 106 => static function ($self, $stackPos) {
  19096. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19097. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19098. }, 107 => static function ($self, $stackPos) {
  19099. $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19100. }, 108 => static function ($self, $stackPos) {
  19101. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19102. }, 109 => static function ($self, $stackPos) {
  19103. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19104. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19105. }, 110 => static function ($self, $stackPos) {
  19106. $self->semValue = [];
  19107. }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => static function ($self, $stackPos) {
  19108. $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19109. }, 116 => static function ($self, $stackPos) {
  19110. $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (3 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19111. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
  19112. $self->checkNamespace($self->semValue);
  19113. }, 117 => static function ($self, $stackPos) {
  19114. $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19115. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
  19116. $self->checkNamespace($self->semValue);
  19117. }, 118 => static function ($self, $stackPos) {
  19118. $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19119. $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
  19120. $self->checkNamespace($self->semValue);
  19121. }, 119 => static function ($self, $stackPos) {
  19122. $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19123. }, 120 => static function ($self, $stackPos) {
  19124. $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19125. }, 121 => null, 122 => static function ($self, $stackPos) {
  19126. $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19127. }, 123 => static function ($self, $stackPos) {
  19128. $self->semValue = Stmt\Use_::TYPE_FUNCTION;
  19129. }, 124 => static function ($self, $stackPos) {
  19130. $self->semValue = Stmt\Use_::TYPE_CONSTANT;
  19131. }, 125 => static function ($self, $stackPos) {
  19132. $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 6)], $self->semStack[$stackPos - (8 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19133. }, 126 => static function ($self, $stackPos) {
  19134. $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19135. }, 127 => null, 128 => static function ($self, $stackPos) {
  19136. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19137. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19138. }, 129 => static function ($self, $stackPos) {
  19139. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19140. }, 130 => null, 131 => static function ($self, $stackPos) {
  19141. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19142. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19143. }, 132 => static function ($self, $stackPos) {
  19144. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19145. }, 133 => null, 134 => static function ($self, $stackPos) {
  19146. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19147. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19148. }, 135 => static function ($self, $stackPos) {
  19149. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19150. }, 136 => static function ($self, $stackPos) {
  19151. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19152. $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
  19153. }, 137 => static function ($self, $stackPos) {
  19154. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19155. $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
  19156. }, 138 => static function ($self, $stackPos) {
  19157. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19158. $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
  19159. }, 139 => static function ($self, $stackPos) {
  19160. $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19161. $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
  19162. }, 140 => static function ($self, $stackPos) {
  19163. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19164. $self->semValue->type = Stmt\Use_::TYPE_NORMAL;
  19165. }, 141 => static function ($self, $stackPos) {
  19166. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19167. $self->semValue->type = $self->semStack[$stackPos - (2 - 1)];
  19168. }, 142 => null, 143 => static function ($self, $stackPos) {
  19169. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19170. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19171. }, 144 => static function ($self, $stackPos) {
  19172. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19173. }, 145 => static function ($self, $stackPos) {
  19174. $self->semValue = new Node\Const_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19175. }, 146 => null, 147 => static function ($self, $stackPos) {
  19176. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19177. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19178. }, 148 => static function ($self, $stackPos) {
  19179. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19180. }, 149 => static function ($self, $stackPos) {
  19181. $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19182. }, 150 => static function ($self, $stackPos) {
  19183. $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19184. }, 151 => static function ($self, $stackPos) {
  19185. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  19186. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19187. }
  19188. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19189. }, 152 => static function ($self, $stackPos) {
  19190. $self->semValue = array();
  19191. }, 153 => static function ($self, $stackPos) {
  19192. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  19193. if ($nop !== null) {
  19194. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  19195. }
  19196. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19197. }, 154 => null, 155 => null, 156 => null, 157 => static function ($self, $stackPos) {
  19198. throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19199. }, 158 => static function ($self, $stackPos) {
  19200. $self->semValue = new Stmt\Block($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19201. }, 159 => static function ($self, $stackPos) {
  19202. $self->semValue = new Stmt\If_($self->semStack[$stackPos - (7 - 3)], ['stmts' => $self->semStack[$stackPos - (7 - 5)], 'elseifs' => $self->semStack[$stackPos - (7 - 6)], 'else' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19203. }, 160 => static function ($self, $stackPos) {
  19204. $self->semValue = new Stmt\If_($self->semStack[$stackPos - (10 - 3)], ['stmts' => $self->semStack[$stackPos - (10 - 6)], 'elseifs' => $self->semStack[$stackPos - (10 - 7)], 'else' => $self->semStack[$stackPos - (10 - 8)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  19205. }, 161 => static function ($self, $stackPos) {
  19206. $self->semValue = new Stmt\While_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19207. }, 162 => static function ($self, $stackPos) {
  19208. $self->semValue = new Stmt\Do_($self->semStack[$stackPos - (7 - 5)], $self->semStack[$stackPos - (7 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19209. }, 163 => static function ($self, $stackPos) {
  19210. $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos - (9 - 3)], 'cond' => $self->semStack[$stackPos - (9 - 5)], 'loop' => $self->semStack[$stackPos - (9 - 7)], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19211. }, 164 => static function ($self, $stackPos) {
  19212. $self->semValue = new Stmt\Switch_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19213. }, 165 => static function ($self, $stackPos) {
  19214. $self->semValue = new Stmt\Break_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19215. }, 166 => static function ($self, $stackPos) {
  19216. $self->semValue = new Stmt\Continue_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19217. }, 167 => static function ($self, $stackPos) {
  19218. $self->semValue = new Stmt\Return_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19219. }, 168 => static function ($self, $stackPos) {
  19220. $self->semValue = new Stmt\Global_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19221. }, 169 => static function ($self, $stackPos) {
  19222. $self->semValue = new Stmt\Static_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19223. }, 170 => static function ($self, $stackPos) {
  19224. $self->semValue = new Stmt\Echo_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19225. }, 171 => static function ($self, $stackPos) {
  19226. $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19227. $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos - (1 - 1)));
  19228. }, 172 => static function ($self, $stackPos) {
  19229. $self->semValue = new Stmt\Expression($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19230. }, 173 => static function ($self, $stackPos) {
  19231. $self->semValue = new Stmt\Unset_($self->semStack[$stackPos - (5 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19232. }, 174 => static function ($self, $stackPos) {
  19233. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos - (7 - 5)][1], 'stmts' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19234. }, 175 => static function ($self, $stackPos) {
  19235. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $self->semStack[$stackPos - (9 - 5)], 'byRef' => $self->semStack[$stackPos - (9 - 7)][1], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19236. }, 176 => static function ($self, $stackPos) {
  19237. $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (6 - 3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 4)], $self->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $self->semStack[$stackPos - (6 - 6)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  19238. }, 177 => static function ($self, $stackPos) {
  19239. $self->semValue = new Stmt\Declare_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19240. }, 178 => static function ($self, $stackPos) {
  19241. $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  19242. $self->checkTryCatch($self->semValue);
  19243. }, 179 => static function ($self, $stackPos) {
  19244. $self->semValue = new Stmt\Goto_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19245. }, 180 => static function ($self, $stackPos) {
  19246. $self->semValue = new Stmt\Label($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19247. }, 181 => static function ($self, $stackPos) {
  19248. $self->semValue = null;
  19249. /* means: no statement */
  19250. }, 182 => null, 183 => static function ($self, $stackPos) {
  19251. $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
  19252. }, 184 => static function ($self, $stackPos) {
  19253. if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
  19254. $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
  19255. } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
  19256. $self->semValue = [];
  19257. } else {
  19258. $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
  19259. }
  19260. }, 185 => static function ($self, $stackPos) {
  19261. $self->semValue = array();
  19262. }, 186 => static function ($self, $stackPos) {
  19263. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19264. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19265. }, 187 => static function ($self, $stackPos) {
  19266. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19267. }, 188 => static function ($self, $stackPos) {
  19268. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19269. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19270. }, 189 => static function ($self, $stackPos) {
  19271. $self->semValue = new Stmt\Catch_($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 7)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19272. }, 190 => static function ($self, $stackPos) {
  19273. $self->semValue = null;
  19274. }, 191 => static function ($self, $stackPos) {
  19275. $self->semValue = new Stmt\Finally_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19276. }, 192 => null, 193 => static function ($self, $stackPos) {
  19277. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19278. }, 194 => static function ($self, $stackPos) {
  19279. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19280. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19281. }, 195 => static function ($self, $stackPos) {
  19282. $self->semValue = \false;
  19283. }, 196 => static function ($self, $stackPos) {
  19284. $self->semValue = \true;
  19285. }, 197 => static function ($self, $stackPos) {
  19286. $self->semValue = \false;
  19287. }, 198 => static function ($self, $stackPos) {
  19288. $self->semValue = \true;
  19289. }, 199 => static function ($self, $stackPos) {
  19290. $self->semValue = \false;
  19291. }, 200 => static function ($self, $stackPos) {
  19292. $self->semValue = \true;
  19293. }, 201 => static function ($self, $stackPos) {
  19294. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19295. }, 202 => static function ($self, $stackPos) {
  19296. $self->semValue = [];
  19297. }, 203 => null, 204 => static function ($self, $stackPos) {
  19298. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19299. }, 205 => static function ($self, $stackPos) {
  19300. $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19301. }, 206 => static function ($self, $stackPos) {
  19302. $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (8 - 3)], ['byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 5)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19303. }, 207 => static function ($self, $stackPos) {
  19304. $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (9 - 4)], ['byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 6)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19305. }, 208 => static function ($self, $stackPos) {
  19306. $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (7 - 2)], ['type' => $self->semStack[$stackPos - (7 - 1)], 'extends' => $self->semStack[$stackPos - (7 - 3)], 'implements' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19307. $self->checkClass($self->semValue, $stackPos - (7 - 2));
  19308. }, 209 => static function ($self, $stackPos) {
  19309. $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (8 - 3)], ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19310. $self->checkClass($self->semValue, $stackPos - (8 - 3));
  19311. }, 210 => static function ($self, $stackPos) {
  19312. $self->semValue = new Stmt\Interface_($self->semStack[$stackPos - (7 - 3)], ['extends' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => $self->semStack[$stackPos - (7 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19313. $self->checkInterface($self->semValue, $stackPos - (7 - 3));
  19314. }, 211 => static function ($self, $stackPos) {
  19315. $self->semValue = new Stmt\Trait_($self->semStack[$stackPos - (6 - 3)], ['stmts' => $self->semStack[$stackPos - (6 - 5)], 'attrGroups' => $self->semStack[$stackPos - (6 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  19316. }, 212 => static function ($self, $stackPos) {
  19317. $self->semValue = new Stmt\Enum_($self->semStack[$stackPos - (8 - 3)], ['scalarType' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19318. $self->checkEnum($self->semValue, $stackPos - (8 - 3));
  19319. }, 213 => static function ($self, $stackPos) {
  19320. $self->semValue = null;
  19321. }, 214 => static function ($self, $stackPos) {
  19322. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19323. }, 215 => static function ($self, $stackPos) {
  19324. $self->semValue = null;
  19325. }, 216 => static function ($self, $stackPos) {
  19326. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19327. }, 217 => static function ($self, $stackPos) {
  19328. $self->semValue = 0;
  19329. }, 218 => null, 219 => null, 220 => static function ($self, $stackPos) {
  19330. $self->checkClassModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  19331. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  19332. }, 221 => static function ($self, $stackPos) {
  19333. $self->semValue = Modifiers::ABSTRACT;
  19334. }, 222 => static function ($self, $stackPos) {
  19335. $self->semValue = Modifiers::FINAL;
  19336. }, 223 => static function ($self, $stackPos) {
  19337. $self->semValue = Modifiers::READONLY;
  19338. }, 224 => static function ($self, $stackPos) {
  19339. $self->semValue = null;
  19340. }, 225 => static function ($self, $stackPos) {
  19341. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19342. }, 226 => static function ($self, $stackPos) {
  19343. $self->semValue = array();
  19344. }, 227 => static function ($self, $stackPos) {
  19345. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19346. }, 228 => static function ($self, $stackPos) {
  19347. $self->semValue = array();
  19348. }, 229 => static function ($self, $stackPos) {
  19349. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19350. }, 230 => null, 231 => static function ($self, $stackPos) {
  19351. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19352. }, 232 => static function ($self, $stackPos) {
  19353. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19354. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19355. }, 233 => null, 234 => static function ($self, $stackPos) {
  19356. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19357. }, 235 => null, 236 => static function ($self, $stackPos) {
  19358. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19359. }, 237 => static function ($self, $stackPos) {
  19360. if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
  19361. $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
  19362. } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
  19363. $self->semValue = [];
  19364. } else {
  19365. $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
  19366. }
  19367. }, 238 => static function ($self, $stackPos) {
  19368. $self->semValue = null;
  19369. }, 239 => static function ($self, $stackPos) {
  19370. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19371. }, 240 => null, 241 => static function ($self, $stackPos) {
  19372. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19373. }, 242 => static function ($self, $stackPos) {
  19374. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19375. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19376. }, 243 => static function ($self, $stackPos) {
  19377. $self->semValue = new Node\DeclareItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19378. }, 244 => static function ($self, $stackPos) {
  19379. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19380. }, 245 => static function ($self, $stackPos) {
  19381. $self->semValue = $self->semStack[$stackPos - (4 - 3)];
  19382. }, 246 => static function ($self, $stackPos) {
  19383. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19384. }, 247 => static function ($self, $stackPos) {
  19385. $self->semValue = $self->semStack[$stackPos - (5 - 3)];
  19386. }, 248 => static function ($self, $stackPos) {
  19387. $self->semValue = array();
  19388. }, 249 => static function ($self, $stackPos) {
  19389. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19390. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19391. }, 250 => static function ($self, $stackPos) {
  19392. $self->semValue = new Stmt\Case_($self->semStack[$stackPos - (4 - 2)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19393. }, 251 => static function ($self, $stackPos) {
  19394. $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19395. }, 252 => null, 253 => null, 254 => static function ($self, $stackPos) {
  19396. $self->semValue = new Expr\Match_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
  19397. }, 255 => static function ($self, $stackPos) {
  19398. $self->semValue = [];
  19399. }, 256 => null, 257 => static function ($self, $stackPos) {
  19400. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19401. }, 258 => static function ($self, $stackPos) {
  19402. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19403. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19404. }, 259 => static function ($self, $stackPos) {
  19405. $self->semValue = new Node\MatchArm($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19406. }, 260 => static function ($self, $stackPos) {
  19407. $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19408. }, 261 => static function ($self, $stackPos) {
  19409. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19410. }, 262 => static function ($self, $stackPos) {
  19411. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19412. }, 263 => static function ($self, $stackPos) {
  19413. $self->semValue = array();
  19414. }, 264 => static function ($self, $stackPos) {
  19415. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19416. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19417. }, 265 => static function ($self, $stackPos) {
  19418. $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19419. }, 266 => static function ($self, $stackPos) {
  19420. $self->semValue = array();
  19421. }, 267 => static function ($self, $stackPos) {
  19422. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19423. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19424. }, 268 => static function ($self, $stackPos) {
  19425. $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  19426. $self->fixupAlternativeElse($self->semValue);
  19427. }, 269 => static function ($self, $stackPos) {
  19428. $self->semValue = null;
  19429. }, 270 => static function ($self, $stackPos) {
  19430. $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19431. }, 271 => static function ($self, $stackPos) {
  19432. $self->semValue = null;
  19433. }, 272 => static function ($self, $stackPos) {
  19434. $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19435. $self->fixupAlternativeElse($self->semValue);
  19436. }, 273 => static function ($self, $stackPos) {
  19437. $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
  19438. }, 274 => static function ($self, $stackPos) {
  19439. $self->semValue = array($self->semStack[$stackPos - (2 - 2)], \true);
  19440. }, 275 => static function ($self, $stackPos) {
  19441. $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
  19442. }, 276 => static function ($self, $stackPos) {
  19443. $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos - (1 - 1)]), \false);
  19444. }, 277 => null, 278 => static function ($self, $stackPos) {
  19445. $self->semValue = array();
  19446. }, 279 => static function ($self, $stackPos) {
  19447. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19448. }, 280 => static function ($self, $stackPos) {
  19449. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19450. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19451. }, 281 => static function ($self, $stackPos) {
  19452. $self->semValue = 0;
  19453. }, 282 => static function ($self, $stackPos) {
  19454. $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  19455. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  19456. }, 283 => static function ($self, $stackPos) {
  19457. $self->semValue = Modifiers::PUBLIC;
  19458. }, 284 => static function ($self, $stackPos) {
  19459. $self->semValue = Modifiers::PROTECTED;
  19460. }, 285 => static function ($self, $stackPos) {
  19461. $self->semValue = Modifiers::PRIVATE;
  19462. }, 286 => static function ($self, $stackPos) {
  19463. $self->semValue = Modifiers::PUBLIC_SET;
  19464. }, 287 => static function ($self, $stackPos) {
  19465. $self->semValue = Modifiers::PROTECTED_SET;
  19466. }, 288 => static function ($self, $stackPos) {
  19467. $self->semValue = Modifiers::PRIVATE_SET;
  19468. }, 289 => static function ($self, $stackPos) {
  19469. $self->semValue = Modifiers::READONLY;
  19470. }, 290 => static function ($self, $stackPos) {
  19471. $self->semValue = new Node\Param($self->semStack[$stackPos - (7 - 6)], null, $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 4)], $self->semStack[$stackPos - (7 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 7)]);
  19472. $self->checkParam($self->semValue);
  19473. }, 291 => static function ($self, $stackPos) {
  19474. $self->semValue = new Node\Param($self->semStack[$stackPos - (9 - 6)], $self->semStack[$stackPos - (9 - 8)], $self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 4)], $self->semStack[$stackPos - (9 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (9 - 2)], $self->semStack[$stackPos - (9 - 1)], $self->semStack[$stackPos - (9 - 9)]);
  19475. $self->checkParam($self->semValue);
  19476. }, 292 => static function ($self, $stackPos) {
  19477. $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 4)], $self->semStack[$stackPos - (6 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 1)]);
  19478. }, 293 => null, 294 => static function ($self, $stackPos) {
  19479. $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19480. }, 295 => static function ($self, $stackPos) {
  19481. $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19482. }, 296 => null, 297 => null, 298 => static function ($self, $stackPos) {
  19483. $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19484. }, 299 => static function ($self, $stackPos) {
  19485. $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos - (1 - 1)]);
  19486. }, 300 => static function ($self, $stackPos) {
  19487. $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19488. }, 301 => static function ($self, $stackPos) {
  19489. $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19490. }, 302 => null, 303 => static function ($self, $stackPos) {
  19491. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19492. }, 304 => static function ($self, $stackPos) {
  19493. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  19494. }, 305 => static function ($self, $stackPos) {
  19495. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19496. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19497. }, 306 => null, 307 => static function ($self, $stackPos) {
  19498. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19499. }, 308 => static function ($self, $stackPos) {
  19500. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  19501. }, 309 => static function ($self, $stackPos) {
  19502. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19503. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19504. }, 310 => static function ($self, $stackPos) {
  19505. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  19506. }, 311 => static function ($self, $stackPos) {
  19507. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19508. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19509. }, 312 => static function ($self, $stackPos) {
  19510. $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19511. }, 313 => static function ($self, $stackPos) {
  19512. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  19513. }, 314 => static function ($self, $stackPos) {
  19514. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19515. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19516. }, 315 => static function ($self, $stackPos) {
  19517. $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19518. }, 316 => null, 317 => static function ($self, $stackPos) {
  19519. $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19520. }, 318 => static function ($self, $stackPos) {
  19521. $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19522. }, 319 => null, 320 => static function ($self, $stackPos) {
  19523. $self->semValue = null;
  19524. }, 321 => null, 322 => static function ($self, $stackPos) {
  19525. $self->semValue = null;
  19526. }, 323 => static function ($self, $stackPos) {
  19527. $self->semValue = $self->semStack[$stackPos - (2 - 2)];
  19528. }, 324 => static function ($self, $stackPos) {
  19529. $self->semValue = null;
  19530. }, 325 => static function ($self, $stackPos) {
  19531. $self->semValue = array();
  19532. }, 326 => static function ($self, $stackPos) {
  19533. $self->semValue = $self->semStack[$stackPos - (4 - 2)];
  19534. }, 327 => static function ($self, $stackPos) {
  19535. $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
  19536. }, 328 => static function ($self, $stackPos) {
  19537. $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19538. }, 329 => static function ($self, $stackPos) {
  19539. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19540. }, 330 => static function ($self, $stackPos) {
  19541. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19542. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19543. }, 331 => static function ($self, $stackPos) {
  19544. $self->semValue = new Node\Arg($self->semStack[$stackPos - (1 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19545. }, 332 => static function ($self, $stackPos) {
  19546. $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \true, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19547. }, 333 => static function ($self, $stackPos) {
  19548. $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \false, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19549. }, 334 => static function ($self, $stackPos) {
  19550. $self->semValue = new Node\Arg($self->semStack[$stackPos - (3 - 3)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (3 - 1)]);
  19551. }, 335 => null, 336 => static function ($self, $stackPos) {
  19552. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19553. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19554. }, 337 => static function ($self, $stackPos) {
  19555. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19556. }, 338 => null, 339 => null, 340 => static function ($self, $stackPos) {
  19557. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19558. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19559. }, 341 => static function ($self, $stackPos) {
  19560. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19561. }, 342 => static function ($self, $stackPos) {
  19562. $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19563. }, 343 => static function ($self, $stackPos) {
  19564. $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19565. }, 344 => static function ($self, $stackPos) {
  19566. if ($self->semStack[$stackPos - (2 - 2)] !== null) {
  19567. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19568. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19569. } else {
  19570. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19571. }
  19572. }, 345 => static function ($self, $stackPos) {
  19573. $self->semValue = array();
  19574. }, 346 => static function ($self, $stackPos) {
  19575. $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
  19576. if ($nop !== null) {
  19577. $self->semStack[$stackPos - (1 - 1)][] = $nop;
  19578. }
  19579. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19580. }, 347 => static function ($self, $stackPos) {
  19581. $self->semValue = new Stmt\Property($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 1)]);
  19582. }, 348 => static function ($self, $stackPos) {
  19583. $self->semValue = new Stmt\Property($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 6)]);
  19584. $self->checkPropertyHookList($self->semStack[$stackPos - (7 - 6)], $stackPos - (7 - 5));
  19585. }, 349 => static function ($self, $stackPos) {
  19586. $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 1)]);
  19587. $self->checkClassConst($self->semValue, $stackPos - (5 - 2));
  19588. }, 350 => static function ($self, $stackPos) {
  19589. $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 1)], $self->semStack[$stackPos - (6 - 4)]);
  19590. $self->checkClassConst($self->semValue, $stackPos - (6 - 2));
  19591. }, 351 => static function ($self, $stackPos) {
  19592. $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos - (10 - 5)], ['type' => $self->semStack[$stackPos - (10 - 2)], 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 7)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  19593. $self->checkClassMethod($self->semValue, $stackPos - (10 - 2));
  19594. }, 352 => static function ($self, $stackPos) {
  19595. $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19596. }, 353 => static function ($self, $stackPos) {
  19597. $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19598. }, 354 => static function ($self, $stackPos) {
  19599. $self->semValue = null;
  19600. /* will be skipped */
  19601. }, 355 => static function ($self, $stackPos) {
  19602. $self->semValue = array();
  19603. }, 356 => static function ($self, $stackPos) {
  19604. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19605. }, 357 => static function ($self, $stackPos) {
  19606. $self->semValue = array();
  19607. }, 358 => static function ($self, $stackPos) {
  19608. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19609. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19610. }, 359 => static function ($self, $stackPos) {
  19611. $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19612. }, 360 => static function ($self, $stackPos) {
  19613. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (5 - 1)][0], $self->semStack[$stackPos - (5 - 1)][1], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19614. }, 361 => static function ($self, $stackPos) {
  19615. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19616. }, 362 => static function ($self, $stackPos) {
  19617. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19618. }, 363 => static function ($self, $stackPos) {
  19619. $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19620. }, 364 => static function ($self, $stackPos) {
  19621. $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
  19622. }, 365 => null, 366 => static function ($self, $stackPos) {
  19623. $self->semValue = array(null, $self->semStack[$stackPos - (1 - 1)]);
  19624. }, 367 => static function ($self, $stackPos) {
  19625. $self->semValue = null;
  19626. }, 368 => null, 369 => null, 370 => static function ($self, $stackPos) {
  19627. $self->semValue = 0;
  19628. }, 371 => static function ($self, $stackPos) {
  19629. $self->semValue = 0;
  19630. }, 372 => null, 373 => null, 374 => static function ($self, $stackPos) {
  19631. $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  19632. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  19633. }, 375 => static function ($self, $stackPos) {
  19634. $self->semValue = Modifiers::PUBLIC;
  19635. }, 376 => static function ($self, $stackPos) {
  19636. $self->semValue = Modifiers::PROTECTED;
  19637. }, 377 => static function ($self, $stackPos) {
  19638. $self->semValue = Modifiers::PRIVATE;
  19639. }, 378 => static function ($self, $stackPos) {
  19640. $self->semValue = Modifiers::PUBLIC_SET;
  19641. }, 379 => static function ($self, $stackPos) {
  19642. $self->semValue = Modifiers::PROTECTED_SET;
  19643. }, 380 => static function ($self, $stackPos) {
  19644. $self->semValue = Modifiers::PRIVATE_SET;
  19645. }, 381 => static function ($self, $stackPos) {
  19646. $self->semValue = Modifiers::STATIC;
  19647. }, 382 => static function ($self, $stackPos) {
  19648. $self->semValue = Modifiers::ABSTRACT;
  19649. }, 383 => static function ($self, $stackPos) {
  19650. $self->semValue = Modifiers::FINAL;
  19651. }, 384 => static function ($self, $stackPos) {
  19652. $self->semValue = Modifiers::READONLY;
  19653. }, 385 => null, 386 => static function ($self, $stackPos) {
  19654. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19655. }, 387 => static function ($self, $stackPos) {
  19656. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19657. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19658. }, 388 => static function ($self, $stackPos) {
  19659. $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19660. }, 389 => static function ($self, $stackPos) {
  19661. $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19662. }, 390 => static function ($self, $stackPos) {
  19663. $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19664. }, 391 => static function ($self, $stackPos) {
  19665. $self->semValue = [];
  19666. }, 392 => static function ($self, $stackPos) {
  19667. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  19668. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  19669. }, 393 => static function ($self, $stackPos) {
  19670. $self->semValue = [];
  19671. }, 394 => static function ($self, $stackPos) {
  19672. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19673. $self->checkPropertyHookList($self->semStack[$stackPos - (3 - 2)], $stackPos - (3 - 1));
  19674. }, 395 => static function ($self, $stackPos) {
  19675. $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 5)], ['flags' => $self->semStack[$stackPos - (5 - 2)], 'byRef' => $self->semStack[$stackPos - (5 - 3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos - (5 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19676. $self->checkPropertyHook($self->semValue, null);
  19677. }, 396 => static function ($self, $stackPos) {
  19678. $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 8)], ['flags' => $self->semStack[$stackPos - (8 - 2)], 'byRef' => $self->semStack[$stackPos - (8 - 3)], 'params' => $self->semStack[$stackPos - (8 - 6)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19679. $self->checkPropertyHook($self->semValue, $stackPos - (8 - 5));
  19680. }, 397 => static function ($self, $stackPos) {
  19681. $self->semValue = null;
  19682. }, 398 => static function ($self, $stackPos) {
  19683. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19684. }, 399 => static function ($self, $stackPos) {
  19685. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19686. }, 400 => static function ($self, $stackPos) {
  19687. $self->semValue = 0;
  19688. }, 401 => static function ($self, $stackPos) {
  19689. $self->checkPropertyHookModifiers($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
  19690. $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
  19691. }, 402 => null, 403 => null, 404 => static function ($self, $stackPos) {
  19692. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19693. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19694. }, 405 => static function ($self, $stackPos) {
  19695. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19696. }, 406 => static function ($self, $stackPos) {
  19697. $self->semValue = array();
  19698. }, 407 => null, 408 => null, 409 => static function ($self, $stackPos) {
  19699. $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19700. }, 410 => static function ($self, $stackPos) {
  19701. $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos - (3 - 1)]), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19702. }, 411 => static function ($self, $stackPos) {
  19703. $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19704. }, 412 => static function ($self, $stackPos) {
  19705. $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19706. }, 413 => static function ($self, $stackPos) {
  19707. $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19708. if (!$self->phpVersion->allowsAssignNewByReference()) {
  19709. $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
  19710. }
  19711. }, 414 => null, 415 => null, 416 => static function ($self, $stackPos) {
  19712. $self->semValue = new Expr\Clone_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19713. }, 417 => static function ($self, $stackPos) {
  19714. $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19715. }, 418 => static function ($self, $stackPos) {
  19716. $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19717. }, 419 => static function ($self, $stackPos) {
  19718. $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19719. }, 420 => static function ($self, $stackPos) {
  19720. $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19721. }, 421 => static function ($self, $stackPos) {
  19722. $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19723. }, 422 => static function ($self, $stackPos) {
  19724. $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19725. }, 423 => static function ($self, $stackPos) {
  19726. $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19727. }, 424 => static function ($self, $stackPos) {
  19728. $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19729. }, 425 => static function ($self, $stackPos) {
  19730. $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19731. }, 426 => static function ($self, $stackPos) {
  19732. $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19733. }, 427 => static function ($self, $stackPos) {
  19734. $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19735. }, 428 => static function ($self, $stackPos) {
  19736. $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19737. }, 429 => static function ($self, $stackPos) {
  19738. $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19739. }, 430 => static function ($self, $stackPos) {
  19740. $self->semValue = new Expr\PostInc($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19741. }, 431 => static function ($self, $stackPos) {
  19742. $self->semValue = new Expr\PreInc($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19743. }, 432 => static function ($self, $stackPos) {
  19744. $self->semValue = new Expr\PostDec($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19745. }, 433 => static function ($self, $stackPos) {
  19746. $self->semValue = new Expr\PreDec($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19747. }, 434 => static function ($self, $stackPos) {
  19748. $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19749. }, 435 => static function ($self, $stackPos) {
  19750. $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19751. }, 436 => static function ($self, $stackPos) {
  19752. $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19753. }, 437 => static function ($self, $stackPos) {
  19754. $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19755. }, 438 => static function ($self, $stackPos) {
  19756. $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19757. }, 439 => static function ($self, $stackPos) {
  19758. $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19759. }, 440 => static function ($self, $stackPos) {
  19760. $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19761. }, 441 => static function ($self, $stackPos) {
  19762. $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19763. }, 442 => static function ($self, $stackPos) {
  19764. $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19765. }, 443 => static function ($self, $stackPos) {
  19766. $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19767. }, 444 => static function ($self, $stackPos) {
  19768. $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19769. }, 445 => static function ($self, $stackPos) {
  19770. $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19771. }, 446 => static function ($self, $stackPos) {
  19772. $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19773. }, 447 => static function ($self, $stackPos) {
  19774. $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19775. }, 448 => static function ($self, $stackPos) {
  19776. $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19777. }, 449 => static function ($self, $stackPos) {
  19778. $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19779. }, 450 => static function ($self, $stackPos) {
  19780. $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19781. }, 451 => static function ($self, $stackPos) {
  19782. $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19783. }, 452 => static function ($self, $stackPos) {
  19784. $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19785. }, 453 => static function ($self, $stackPos) {
  19786. $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19787. }, 454 => static function ($self, $stackPos) {
  19788. $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19789. }, 455 => static function ($self, $stackPos) {
  19790. $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19791. }, 456 => static function ($self, $stackPos) {
  19792. $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19793. }, 457 => static function ($self, $stackPos) {
  19794. $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19795. }, 458 => static function ($self, $stackPos) {
  19796. $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19797. }, 459 => static function ($self, $stackPos) {
  19798. $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19799. }, 460 => static function ($self, $stackPos) {
  19800. $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19801. }, 461 => static function ($self, $stackPos) {
  19802. $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19803. }, 462 => static function ($self, $stackPos) {
  19804. $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19805. }, 463 => static function ($self, $stackPos) {
  19806. $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19807. }, 464 => static function ($self, $stackPos) {
  19808. $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19809. }, 465 => static function ($self, $stackPos) {
  19810. $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19811. }, 466 => static function ($self, $stackPos) {
  19812. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19813. }, 467 => static function ($self, $stackPos) {
  19814. $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19815. }, 468 => static function ($self, $stackPos) {
  19816. $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (4 - 1)], null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19817. }, 469 => static function ($self, $stackPos) {
  19818. $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19819. }, 470 => static function ($self, $stackPos) {
  19820. $self->semValue = new Expr\Isset_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19821. }, 471 => static function ($self, $stackPos) {
  19822. $self->semValue = new Expr\Empty_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19823. }, 472 => static function ($self, $stackPos) {
  19824. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19825. }, 473 => static function ($self, $stackPos) {
  19826. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19827. }, 474 => static function ($self, $stackPos) {
  19828. $self->semValue = new Expr\Eval_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19829. }, 475 => static function ($self, $stackPos) {
  19830. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19831. }, 476 => static function ($self, $stackPos) {
  19832. $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19833. }, 477 => static function ($self, $stackPos) {
  19834. $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19835. }, 478 => static function ($self, $stackPos) {
  19836. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
  19837. $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos - (2 - 1)]);
  19838. $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos - (2 - 2)], $attrs);
  19839. }, 479 => static function ($self, $stackPos) {
  19840. $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19841. }, 480 => static function ($self, $stackPos) {
  19842. $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19843. }, 481 => static function ($self, $stackPos) {
  19844. $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19845. }, 482 => static function ($self, $stackPos) {
  19846. $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19847. }, 483 => static function ($self, $stackPos) {
  19848. $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19849. }, 484 => static function ($self, $stackPos) {
  19850. $self->semValue = $self->createExitExpr($self->semStack[$stackPos - (2 - 1)], $stackPos - (2 - 1), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19851. }, 485 => static function ($self, $stackPos) {
  19852. $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19853. }, 486 => null, 487 => static function ($self, $stackPos) {
  19854. $self->semValue = new Expr\ShellExec($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19855. }, 488 => static function ($self, $stackPos) {
  19856. $self->semValue = new Expr\Print_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19857. }, 489 => static function ($self, $stackPos) {
  19858. $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19859. }, 490 => static function ($self, $stackPos) {
  19860. $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (2 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19861. }, 491 => static function ($self, $stackPos) {
  19862. $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19863. }, 492 => static function ($self, $stackPos) {
  19864. $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19865. }, 493 => static function ($self, $stackPos) {
  19866. $self->semValue = new Expr\Throw_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19867. }, 494 => static function ($self, $stackPos) {
  19868. $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'returnType' => $self->semStack[$stackPos - (8 - 6)], 'expr' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19869. }, 495 => static function ($self, $stackPos) {
  19870. $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19871. }, 496 => static function ($self, $stackPos) {
  19872. $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'uses' => $self->semStack[$stackPos - (8 - 6)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
  19873. }, 497 => static function ($self, $stackPos) {
  19874. $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19875. }, 498 => static function ($self, $stackPos) {
  19876. $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19877. }, 499 => static function ($self, $stackPos) {
  19878. $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'returnType' => $self->semStack[$stackPos - (10 - 8)], 'expr' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  19879. }, 500 => static function ($self, $stackPos) {
  19880. $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
  19881. }, 501 => static function ($self, $stackPos) {
  19882. $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'uses' => $self->semStack[$stackPos - (10 - 8)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
  19883. }, 502 => static function ($self, $stackPos) {
  19884. $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos - (8 - 3)]);
  19885. $self->checkClass($self->semValue[0], -1);
  19886. }, 503 => static function ($self, $stackPos) {
  19887. $self->semValue = new Expr\New_($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19888. }, 504 => static function ($self, $stackPos) {
  19889. list($class, $ctorArgs) = $self->semStack[$stackPos - (2 - 2)];
  19890. $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19891. }, 505 => static function ($self, $stackPos) {
  19892. $self->semValue = new Expr\New_($self->semStack[$stackPos - (2 - 2)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19893. }, 506 => null, 507 => null, 508 => static function ($self, $stackPos) {
  19894. $self->semValue = array();
  19895. }, 509 => static function ($self, $stackPos) {
  19896. $self->semValue = $self->semStack[$stackPos - (4 - 3)];
  19897. }, 510 => null, 511 => static function ($self, $stackPos) {
  19898. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19899. }, 512 => static function ($self, $stackPos) {
  19900. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  19901. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  19902. }, 513 => static function ($self, $stackPos) {
  19903. $self->semValue = new Node\ClosureUse($self->semStack[$stackPos - (2 - 2)], $self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19904. }, 514 => static function ($self, $stackPos) {
  19905. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19906. }, 515 => static function ($self, $stackPos) {
  19907. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19908. }, 516 => static function ($self, $stackPos) {
  19909. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19910. }, 517 => static function ($self, $stackPos) {
  19911. $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  19912. }, 518 => static function ($self, $stackPos) {
  19913. $self->semValue = new Expr\StaticCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  19914. }, 519 => static function ($self, $stackPos) {
  19915. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19916. }, 520 => null, 521 => static function ($self, $stackPos) {
  19917. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19918. }, 522 => static function ($self, $stackPos) {
  19919. $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19920. }, 523 => static function ($self, $stackPos) {
  19921. $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19922. }, 524 => static function ($self, $stackPos) {
  19923. $self->semValue = new Name\Relative(substr($self->semStack[$stackPos - (1 - 1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19924. }, 525 => null, 526 => null, 527 => static function ($self, $stackPos) {
  19925. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  19926. }, 528 => static function ($self, $stackPos) {
  19927. $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19928. $self->errorState = 2;
  19929. }, 529 => null, 530 => null, 531 => static function ($self, $stackPos) {
  19930. $self->semValue = array();
  19931. }, 532 => static function ($self, $stackPos) {
  19932. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  19933. foreach ($self->semValue as $s) {
  19934. if ($s instanceof Node\InterpolatedStringPart) {
  19935. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
  19936. }
  19937. }
  19938. }, 533 => static function ($self, $stackPos) {
  19939. foreach ($self->semStack[$stackPos - (1 - 1)] as $s) {
  19940. if ($s instanceof Node\InterpolatedStringPart) {
  19941. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
  19942. }
  19943. }
  19944. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19945. }, 534 => static function ($self, $stackPos) {
  19946. $self->semValue = array();
  19947. }, 535 => null, 536 => static function ($self, $stackPos) {
  19948. $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19949. }, 537 => static function ($self, $stackPos) {
  19950. $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19951. }, 538 => static function ($self, $stackPos) {
  19952. $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19953. }, 539 => static function ($self, $stackPos) {
  19954. $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19955. }, 540 => static function ($self, $stackPos) {
  19956. $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19957. }, 541 => static function ($self, $stackPos) {
  19958. $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19959. }, 542 => static function ($self, $stackPos) {
  19960. $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19961. }, 543 => static function ($self, $stackPos) {
  19962. $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19963. }, 544 => static function ($self, $stackPos) {
  19964. $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19965. }, 545 => static function ($self, $stackPos) {
  19966. $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  19967. }, 546 => static function ($self, $stackPos) {
  19968. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19969. }, 547 => static function ($self, $stackPos) {
  19970. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
  19971. }, 548 => static function ($self, $stackPos) {
  19972. $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)])), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  19973. $self->errorState = 2;
  19974. }, 549 => static function ($self, $stackPos) {
  19975. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
  19976. $attrs['kind'] = Expr\Array_::KIND_SHORT;
  19977. $self->semValue = new Expr\Array_($self->semStack[$stackPos - (3 - 2)], $attrs);
  19978. }, 550 => static function ($self, $stackPos) {
  19979. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]);
  19980. $attrs['kind'] = Expr\Array_::KIND_LONG;
  19981. $self->semValue = new Expr\Array_($self->semStack[$stackPos - (4 - 3)], $attrs);
  19982. $self->createdArrays->attach($self->semValue);
  19983. }, 551 => static function ($self, $stackPos) {
  19984. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  19985. $self->createdArrays->attach($self->semValue);
  19986. }, 552 => static function ($self, $stackPos) {
  19987. $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes());
  19988. }, 553 => static function ($self, $stackPos) {
  19989. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
  19990. $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
  19991. foreach ($self->semStack[$stackPos - (3 - 2)] as $s) {
  19992. if ($s instanceof Node\InterpolatedStringPart) {
  19993. $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes());
  19994. }
  19995. }
  19996. $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos - (3 - 2)], $attrs);
  19997. }, 554 => static function ($self, $stackPos) {
  19998. $self->semValue = $self->parseLNumber($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals());
  19999. }, 555 => static function ($self, $stackPos) {
  20000. $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20001. }, 556 => null, 557 => null, 558 => null, 559 => static function ($self, $stackPos) {
  20002. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
  20003. }, 560 => static function ($self, $stackPos) {
  20004. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (2 - 1)], '', $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 2)], $self->tokenEndStack[$stackPos - (2 - 2)]), \true);
  20005. }, 561 => static function ($self, $stackPos) {
  20006. $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
  20007. }, 562 => static function ($self, $stackPos) {
  20008. $self->semValue = null;
  20009. }, 563 => null, 564 => null, 565 => static function ($self, $stackPos) {
  20010. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  20011. }, 566 => null, 567 => null, 568 => null, 569 => null, 570 => null, 571 => null, 572 => static function ($self, $stackPos) {
  20012. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  20013. }, 573 => null, 574 => null, 575 => null, 576 => static function ($self, $stackPos) {
  20014. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20015. }, 577 => null, 578 => static function ($self, $stackPos) {
  20016. $self->semValue = new Expr\MethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20017. }, 579 => static function ($self, $stackPos) {
  20018. $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20019. }, 580 => static function ($self, $stackPos) {
  20020. $self->semValue = null;
  20021. }, 581 => null, 582 => null, 583 => null, 584 => static function ($self, $stackPos) {
  20022. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20023. }, 585 => static function ($self, $stackPos) {
  20024. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20025. }, 586 => null, 587 => static function ($self, $stackPos) {
  20026. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20027. }, 588 => static function ($self, $stackPos) {
  20028. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  20029. }, 589 => static function ($self, $stackPos) {
  20030. $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  20031. $self->errorState = 2;
  20032. }, 590 => static function ($self, $stackPos) {
  20033. $var = $self->semStack[$stackPos - (1 - 1)]->name;
  20034. $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])) : $var;
  20035. }, 591 => static function ($self, $stackPos) {
  20036. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20037. }, 592 => null, 593 => static function ($self, $stackPos) {
  20038. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20039. }, 594 => static function ($self, $stackPos) {
  20040. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20041. }, 595 => static function ($self, $stackPos) {
  20042. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20043. }, 596 => static function ($self, $stackPos) {
  20044. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20045. }, 597 => static function ($self, $stackPos) {
  20046. $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20047. }, 598 => null, 599 => static function ($self, $stackPos) {
  20048. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  20049. }, 600 => null, 601 => null, 602 => static function ($self, $stackPos) {
  20050. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  20051. }, 603 => null, 604 => static function ($self, $stackPos) {
  20052. $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20053. $self->errorState = 2;
  20054. }, 605 => static function ($self, $stackPos) {
  20055. $self->semValue = new Expr\List_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20056. $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST);
  20057. $self->postprocessList($self->semValue);
  20058. }, 606 => static function ($self, $stackPos) {
  20059. $self->semValue = $self->semStack[$stackPos - (1 - 1)];
  20060. $end = count($self->semValue) - 1;
  20061. if ($self->semValue[$end]->value instanceof Expr\Error) {
  20062. array_pop($self->semValue);
  20063. }
  20064. }, 607 => null, 608 => static function ($self, $stackPos) {
  20065. /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */
  20066. }, 609 => static function ($self, $stackPos) {
  20067. $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
  20068. $self->semValue = $self->semStack[$stackPos - (3 - 1)];
  20069. }, 610 => static function ($self, $stackPos) {
  20070. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  20071. }, 611 => static function ($self, $stackPos) {
  20072. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20073. }, 612 => static function ($self, $stackPos) {
  20074. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  20075. }, 613 => static function ($self, $stackPos) {
  20076. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20077. }, 614 => static function ($self, $stackPos) {
  20078. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20079. }, 615 => static function ($self, $stackPos) {
  20080. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 1)], \true, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20081. }, 616 => static function ($self, $stackPos) {
  20082. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20083. }, 617 => static function ($self, $stackPos) {
  20084. $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), \true);
  20085. }, 618 => static function ($self, $stackPos) {
  20086. /* Create an Error node now to remember the position. We'll later either report an error,
  20087. or convert this into a null element, depending on whether this is a creation or destructuring context. */
  20088. $attrs = $self->createEmptyElemAttributes($self->tokenPos);
  20089. $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs);
  20090. }, 619 => static function ($self, $stackPos) {
  20091. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  20092. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  20093. }, 620 => static function ($self, $stackPos) {
  20094. $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
  20095. $self->semValue = $self->semStack[$stackPos - (2 - 1)];
  20096. }, 621 => static function ($self, $stackPos) {
  20097. $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
  20098. }, 622 => static function ($self, $stackPos) {
  20099. $self->semValue = array($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)]);
  20100. }, 623 => static function ($self, $stackPos) {
  20101. $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
  20102. $attrs['rawValue'] = $self->semStack[$stackPos - (1 - 1)];
  20103. $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos - (1 - 1)], $attrs);
  20104. }, 624 => static function ($self, $stackPos) {
  20105. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20106. }, 625 => null, 626 => static function ($self, $stackPos) {
  20107. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
  20108. }, 627 => static function ($self, $stackPos) {
  20109. $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20110. }, 628 => static function ($self, $stackPos) {
  20111. $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20112. }, 629 => static function ($self, $stackPos) {
  20113. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20114. }, 630 => static function ($self, $stackPos) {
  20115. $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
  20116. }, 631 => static function ($self, $stackPos) {
  20117. $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
  20118. }, 632 => static function ($self, $stackPos) {
  20119. $self->semValue = $self->semStack[$stackPos - (3 - 2)];
  20120. }, 633 => static function ($self, $stackPos) {
  20121. $self->semValue = new Scalar\String_($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20122. }, 634 => static function ($self, $stackPos) {
  20123. $self->semValue = $self->parseNumString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
  20124. }, 635 => static function ($self, $stackPos) {
  20125. $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
  20126. }, 636 => null];
  20127. }
  20128. }
  20129. <?php
  20130. declare (strict_types=1);
  20131. namespace PHPUnitPHAR\PhpParser;
  20132. /*
  20133. * This parser is based on a skeleton written by Moriyoshi Koizumi, which in
  20134. * turn is based on work by Masato Bito.
  20135. */
  20136. use PHPUnitPHAR\PhpParser\Node\Arg;
  20137. use PHPUnitPHAR\PhpParser\Node\Expr;
  20138. use PHPUnitPHAR\PhpParser\Node\Expr\Array_;
  20139. use PHPUnitPHAR\PhpParser\Node\Expr\Cast\Double;
  20140. use PHPUnitPHAR\PhpParser\Node\Identifier;
  20141. use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
  20142. use PHPUnitPHAR\PhpParser\Node\Name;
  20143. use PHPUnitPHAR\PhpParser\Node\Param;
  20144. use PHPUnitPHAR\PhpParser\Node\PropertyHook;
  20145. use PHPUnitPHAR\PhpParser\Node\Scalar\InterpolatedString;
  20146. use PHPUnitPHAR\PhpParser\Node\Scalar\Int_;
  20147. use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
  20148. use PHPUnitPHAR\PhpParser\Node\Stmt;
  20149. use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
  20150. use PHPUnitPHAR\PhpParser\Node\Stmt\ClassConst;
  20151. use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
  20152. use PHPUnitPHAR\PhpParser\Node\Stmt\Else_;
  20153. use PHPUnitPHAR\PhpParser\Node\Stmt\ElseIf_;
  20154. use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
  20155. use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
  20156. use PHPUnitPHAR\PhpParser\Node\Stmt\Namespace_;
  20157. use PHPUnitPHAR\PhpParser\Node\Stmt\Nop;
  20158. use PHPUnitPHAR\PhpParser\Node\Stmt\Property;
  20159. use PHPUnitPHAR\PhpParser\Node\Stmt\TryCatch;
  20160. use PHPUnitPHAR\PhpParser\Node\UseItem;
  20161. use PHPUnitPHAR\PhpParser\NodeVisitor\CommentAnnotatingVisitor;
  20162. abstract class ParserAbstract implements Parser
  20163. {
  20164. private const SYMBOL_NONE = -1;
  20165. /** @var Lexer Lexer that is used when parsing */
  20166. protected Lexer $lexer;
  20167. /** @var PhpVersion PHP version to target on a best-effort basis */
  20168. protected PhpVersion $phpVersion;
  20169. /*
  20170. * The following members will be filled with generated parsing data:
  20171. */
  20172. /** @var int Size of $tokenToSymbol map */
  20173. protected int $tokenToSymbolMapSize;
  20174. /** @var int Size of $action table */
  20175. protected int $actionTableSize;
  20176. /** @var int Size of $goto table */
  20177. protected int $gotoTableSize;
  20178. /** @var int Symbol number signifying an invalid token */
  20179. protected int $invalidSymbol;
  20180. /** @var int Symbol number of error recovery token */
  20181. protected int $errorSymbol;
  20182. /** @var int Action number signifying default action */
  20183. protected int $defaultAction;
  20184. /** @var int Rule number signifying that an unexpected token was encountered */
  20185. protected int $unexpectedTokenRule;
  20186. protected int $YY2TBLSTATE;
  20187. /** @var int Number of non-leaf states */
  20188. protected int $numNonLeafStates;
  20189. /** @var int[] Map of PHP token IDs to internal symbols */
  20190. protected array $phpTokenToSymbol;
  20191. /** @var array<int, bool> Map of PHP token IDs to drop */
  20192. protected array $dropTokens;
  20193. /** @var int[] Map of external symbols (static::T_*) to internal symbols */
  20194. protected array $tokenToSymbol;
  20195. /** @var string[] Map of symbols to their names */
  20196. protected array $symbolToName;
  20197. /** @var array<int, string> Names of the production rules (only necessary for debugging) */
  20198. protected array $productions;
  20199. /** @var int[] Map of states to a displacement into the $action table. The corresponding action for this
  20200. * state/symbol pair is $action[$actionBase[$state] + $symbol]. If $actionBase[$state] is 0, the
  20201. * action is defaulted, i.e. $actionDefault[$state] should be used instead. */
  20202. protected array $actionBase;
  20203. /** @var int[] Table of actions. Indexed according to $actionBase comment. */
  20204. protected array $action;
  20205. /** @var int[] Table indexed analogously to $action. If $actionCheck[$actionBase[$state] + $symbol] != $symbol
  20206. * then the action is defaulted, i.e. $actionDefault[$state] should be used instead. */
  20207. protected array $actionCheck;
  20208. /** @var int[] Map of states to their default action */
  20209. protected array $actionDefault;
  20210. /** @var callable[] Semantic action callbacks */
  20211. protected array $reduceCallbacks;
  20212. /** @var int[] Map of non-terminals to a displacement into the $goto table. The corresponding goto state for this
  20213. * non-terminal/state pair is $goto[$gotoBase[$nonTerminal] + $state] (unless defaulted) */
  20214. protected array $gotoBase;
  20215. /** @var int[] Table of states to goto after reduction. Indexed according to $gotoBase comment. */
  20216. protected array $goto;
  20217. /** @var int[] Table indexed analogously to $goto. If $gotoCheck[$gotoBase[$nonTerminal] + $state] != $nonTerminal
  20218. * then the goto state is defaulted, i.e. $gotoDefault[$nonTerminal] should be used. */
  20219. protected array $gotoCheck;
  20220. /** @var int[] Map of non-terminals to the default state to goto after their reduction */
  20221. protected array $gotoDefault;
  20222. /** @var int[] Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for
  20223. * determining the state to goto after reduction. */
  20224. protected array $ruleToNonTerminal;
  20225. /** @var int[] Map of rules to the length of their right-hand side, which is the number of elements that have to
  20226. * be popped from the stack(s) on reduction. */
  20227. protected array $ruleToLength;
  20228. /*
  20229. * The following members are part of the parser state:
  20230. */
  20231. /** @var mixed Temporary value containing the result of last semantic action (reduction) */
  20232. protected $semValue;
  20233. /** @var mixed[] Semantic value stack (contains values of tokens and semantic action results) */
  20234. protected array $semStack;
  20235. /** @var int[] Token start position stack */
  20236. protected array $tokenStartStack;
  20237. /** @var int[] Token end position stack */
  20238. protected array $tokenEndStack;
  20239. /** @var ErrorHandler Error handler */
  20240. protected ErrorHandler $errorHandler;
  20241. /** @var int Error state, used to avoid error floods */
  20242. protected int $errorState;
  20243. /** @var \SplObjectStorage<Array_, null>|null Array nodes created during parsing, for postprocessing of empty elements. */
  20244. protected ?\SplObjectStorage $createdArrays;
  20245. /** @var Token[] Tokens for the current parse */
  20246. protected array $tokens;
  20247. /** @var int Current position in token array */
  20248. protected int $tokenPos;
  20249. /**
  20250. * Initialize $reduceCallbacks map.
  20251. */
  20252. abstract protected function initReduceCallbacks(): void;
  20253. /**
  20254. * Creates a parser instance.
  20255. *
  20256. * Options:
  20257. * * phpVersion: ?PhpVersion,
  20258. *
  20259. * @param Lexer $lexer A lexer
  20260. * @param PhpVersion $phpVersion PHP version to target, defaults to latest supported. This
  20261. * option is best-effort: Even if specified, parsing will generally assume the latest
  20262. * supported version and only adjust behavior in minor ways, for example by omitting
  20263. * errors in older versions and interpreting type hints as a name or identifier depending
  20264. * on version.
  20265. */
  20266. public function __construct(Lexer $lexer, ?PhpVersion $phpVersion = null)
  20267. {
  20268. $this->lexer = $lexer;
  20269. $this->phpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
  20270. $this->initReduceCallbacks();
  20271. $this->phpTokenToSymbol = $this->createTokenMap();
  20272. $this->dropTokens = array_fill_keys([\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], \true);
  20273. }
  20274. /**
  20275. * Parses PHP code into a node tree.
  20276. *
  20277. * If a non-throwing error handler is used, the parser will continue parsing after an error
  20278. * occurred and attempt to build a partial AST.
  20279. *
  20280. * @param string $code The source code to parse
  20281. * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
  20282. * to ErrorHandler\Throwing.
  20283. *
  20284. * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
  20285. * the parser was unable to recover from an error).
  20286. */
  20287. public function parse(string $code, ?ErrorHandler $errorHandler = null): ?array
  20288. {
  20289. $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing();
  20290. $this->createdArrays = new \SplObjectStorage();
  20291. $this->tokens = $this->lexer->tokenize($code, $this->errorHandler);
  20292. $result = $this->doParse();
  20293. // Report errors for any empty elements used inside arrays. This is delayed until after the main parse,
  20294. // because we don't know a priori whether a given array expression will be used in a destructuring context
  20295. // or not.
  20296. foreach ($this->createdArrays as $node) {
  20297. foreach ($node->items as $item) {
  20298. if ($item->value instanceof Expr\Error) {
  20299. $this->errorHandler->handleError(new Error('Cannot use empty array elements in arrays', $item->getAttributes()));
  20300. }
  20301. }
  20302. }
  20303. // Clear out some of the interior state, so we don't hold onto unnecessary
  20304. // memory between uses of the parser
  20305. $this->tokenStartStack = [];
  20306. $this->tokenEndStack = [];
  20307. $this->semStack = [];
  20308. $this->semValue = null;
  20309. $this->createdArrays = null;
  20310. if ($result !== null) {
  20311. $traverser = new NodeTraverser(new CommentAnnotatingVisitor($this->tokens));
  20312. $traverser->traverse($result);
  20313. }
  20314. return $result;
  20315. }
  20316. public function getTokens(): array
  20317. {
  20318. return $this->tokens;
  20319. }
  20320. /** @return Stmt[]|null */
  20321. protected function doParse(): ?array
  20322. {
  20323. // We start off with no lookahead-token
  20324. $symbol = self::SYMBOL_NONE;
  20325. $tokenValue = null;
  20326. $this->tokenPos = -1;
  20327. // Keep stack of start and end attributes
  20328. $this->tokenStartStack = [];
  20329. $this->tokenEndStack = [0];
  20330. // Start off in the initial state and keep a stack of previous states
  20331. $state = 0;
  20332. $stateStack = [$state];
  20333. // Semantic value stack (contains values of tokens and semantic action results)
  20334. $this->semStack = [];
  20335. // Current position in the stack(s)
  20336. $stackPos = 0;
  20337. $this->errorState = 0;
  20338. for (;;) {
  20339. //$this->traceNewState($state, $symbol);
  20340. if ($this->actionBase[$state] === 0) {
  20341. $rule = $this->actionDefault[$state];
  20342. } else {
  20343. if ($symbol === self::SYMBOL_NONE) {
  20344. do {
  20345. $token = $this->tokens[++$this->tokenPos];
  20346. $tokenId = $token->id;
  20347. } while (isset($this->dropTokens[$tokenId]));
  20348. // Map the lexer token id to the internally used symbols.
  20349. $tokenValue = $token->text;
  20350. if (!isset($this->phpTokenToSymbol[$tokenId])) {
  20351. throw new \RangeException(sprintf('The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue));
  20352. }
  20353. $symbol = $this->phpTokenToSymbol[$tokenId];
  20354. //$this->traceRead($symbol);
  20355. }
  20356. $idx = $this->actionBase[$state] + $symbol;
  20357. if (($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) && ($action = $this->action[$idx]) !== $this->defaultAction) {
  20358. /*
  20359. * >= numNonLeafStates: shift and reduce
  20360. * > 0: shift
  20361. * = 0: accept
  20362. * < 0: reduce
  20363. * = -YYUNEXPECTED: error
  20364. */
  20365. if ($action > 0) {
  20366. /* shift */
  20367. //$this->traceShift($symbol);
  20368. ++$stackPos;
  20369. $stateStack[$stackPos] = $state = $action;
  20370. $this->semStack[$stackPos] = $tokenValue;
  20371. $this->tokenStartStack[$stackPos] = $this->tokenPos;
  20372. $this->tokenEndStack[$stackPos] = $this->tokenPos;
  20373. $symbol = self::SYMBOL_NONE;
  20374. if ($this->errorState) {
  20375. --$this->errorState;
  20376. }
  20377. if ($action < $this->numNonLeafStates) {
  20378. continue;
  20379. }
  20380. /* $yyn >= numNonLeafStates means shift-and-reduce */
  20381. $rule = $action - $this->numNonLeafStates;
  20382. } else {
  20383. $rule = -$action;
  20384. }
  20385. } else {
  20386. $rule = $this->actionDefault[$state];
  20387. }
  20388. }
  20389. for (;;) {
  20390. if ($rule === 0) {
  20391. /* accept */
  20392. //$this->traceAccept();
  20393. return $this->semValue;
  20394. }
  20395. if ($rule !== $this->unexpectedTokenRule) {
  20396. /* reduce */
  20397. //$this->traceReduce($rule);
  20398. $ruleLength = $this->ruleToLength[$rule];
  20399. try {
  20400. $callback = $this->reduceCallbacks[$rule];
  20401. if ($callback !== null) {
  20402. $callback($this, $stackPos);
  20403. } elseif ($ruleLength > 0) {
  20404. $this->semValue = $this->semStack[$stackPos - $ruleLength + 1];
  20405. }
  20406. } catch (Error $e) {
  20407. if (-1 === $e->getStartLine()) {
  20408. $e->setStartLine($this->tokens[$this->tokenPos]->line);
  20409. }
  20410. $this->emitError($e);
  20411. // Can't recover from this type of error
  20412. return null;
  20413. }
  20414. /* Goto - shift nonterminal */
  20415. $lastTokenEnd = $this->tokenEndStack[$stackPos];
  20416. $stackPos -= $ruleLength;
  20417. $nonTerminal = $this->ruleToNonTerminal[$rule];
  20418. $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos];
  20419. if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) {
  20420. $state = $this->goto[$idx];
  20421. } else {
  20422. $state = $this->gotoDefault[$nonTerminal];
  20423. }
  20424. ++$stackPos;
  20425. $stateStack[$stackPos] = $state;
  20426. $this->semStack[$stackPos] = $this->semValue;
  20427. $this->tokenEndStack[$stackPos] = $lastTokenEnd;
  20428. if ($ruleLength === 0) {
  20429. // Empty productions use the start attributes of the lookahead token.
  20430. $this->tokenStartStack[$stackPos] = $this->tokenPos;
  20431. }
  20432. } else {
  20433. /* error */
  20434. switch ($this->errorState) {
  20435. case 0:
  20436. $msg = $this->getErrorMessage($symbol, $state);
  20437. $this->emitError(new Error($msg, $this->getAttributesForToken($this->tokenPos)));
  20438. // Break missing intentionally
  20439. // no break
  20440. case 1:
  20441. case 2:
  20442. $this->errorState = 3;
  20443. // Pop until error-expecting state uncovered
  20444. while (!(($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) || ($action = $this->action[$idx]) === $this->defaultAction) {
  20445. // Not totally sure about this
  20446. if ($stackPos <= 0) {
  20447. // Could not recover from error
  20448. return null;
  20449. }
  20450. $state = $stateStack[--$stackPos];
  20451. //$this->tracePop($state);
  20452. }
  20453. //$this->traceShift($this->errorSymbol);
  20454. ++$stackPos;
  20455. $stateStack[$stackPos] = $state = $action;
  20456. // We treat the error symbol as being empty, so we reset the end attributes
  20457. // to the end attributes of the last non-error symbol
  20458. $this->tokenStartStack[$stackPos] = $this->tokenPos;
  20459. $this->tokenEndStack[$stackPos] = $this->tokenEndStack[$stackPos - 1];
  20460. break;
  20461. case 3:
  20462. if ($symbol === 0) {
  20463. // Reached EOF without recovering from error
  20464. return null;
  20465. }
  20466. //$this->traceDiscard($symbol);
  20467. $symbol = self::SYMBOL_NONE;
  20468. break 2;
  20469. }
  20470. }
  20471. if ($state < $this->numNonLeafStates) {
  20472. break;
  20473. }
  20474. /* >= numNonLeafStates means shift-and-reduce */
  20475. $rule = $state - $this->numNonLeafStates;
  20476. }
  20477. }
  20478. throw new \RuntimeException('Reached end of parser loop');
  20479. }
  20480. protected function emitError(Error $error): void
  20481. {
  20482. $this->errorHandler->handleError($error);
  20483. }
  20484. /**
  20485. * Format error message including expected tokens.
  20486. *
  20487. * @param int $symbol Unexpected symbol
  20488. * @param int $state State at time of error
  20489. *
  20490. * @return string Formatted error message
  20491. */
  20492. protected function getErrorMessage(int $symbol, int $state): string
  20493. {
  20494. $expectedString = '';
  20495. if ($expected = $this->getExpectedTokens($state)) {
  20496. $expectedString = ', expecting ' . implode(' or ', $expected);
  20497. }
  20498. return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString;
  20499. }
  20500. /**
  20501. * Get limited number of expected tokens in given state.
  20502. *
  20503. * @param int $state State
  20504. *
  20505. * @return string[] Expected tokens. If too many, an empty array is returned.
  20506. */
  20507. protected function getExpectedTokens(int $state): array
  20508. {
  20509. $expected = [];
  20510. $base = $this->actionBase[$state];
  20511. foreach ($this->symbolToName as $symbol => $name) {
  20512. $idx = $base + $symbol;
  20513. if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) {
  20514. if ($this->action[$idx] !== $this->unexpectedTokenRule && $this->action[$idx] !== $this->defaultAction && $symbol !== $this->errorSymbol) {
  20515. if (count($expected) === 4) {
  20516. /* Too many expected tokens */
  20517. return [];
  20518. }
  20519. $expected[] = $name;
  20520. }
  20521. }
  20522. }
  20523. return $expected;
  20524. }
  20525. /**
  20526. * Get attributes for a node with the given start and end token positions.
  20527. *
  20528. * @param int $tokenStartPos Token position the node starts at
  20529. * @param int $tokenEndPos Token position the node ends at
  20530. * @return array<string, mixed> Attributes
  20531. */
  20532. protected function getAttributes(int $tokenStartPos, int $tokenEndPos): array
  20533. {
  20534. $startToken = $this->tokens[$tokenStartPos];
  20535. $afterEndToken = $this->tokens[$tokenEndPos + 1];
  20536. return ['startLine' => $startToken->line, 'startTokenPos' => $tokenStartPos, 'startFilePos' => $startToken->pos, 'endLine' => $afterEndToken->line, 'endTokenPos' => $tokenEndPos, 'endFilePos' => $afterEndToken->pos - 1];
  20537. }
  20538. /**
  20539. * Get attributes for a single token at the given token position.
  20540. *
  20541. * @return array<string, mixed> Attributes
  20542. */
  20543. protected function getAttributesForToken(int $tokenPos): array
  20544. {
  20545. if ($tokenPos < \count($this->tokens) - 1) {
  20546. return $this->getAttributes($tokenPos, $tokenPos);
  20547. }
  20548. // Get attributes for the sentinel token.
  20549. $token = $this->tokens[$tokenPos];
  20550. return ['startLine' => $token->line, 'startTokenPos' => $tokenPos, 'startFilePos' => $token->pos, 'endLine' => $token->line, 'endTokenPos' => $tokenPos, 'endFilePos' => $token->pos];
  20551. }
  20552. /*
  20553. * Tracing functions used for debugging the parser.
  20554. */
  20555. /*
  20556. protected function traceNewState($state, $symbol): void {
  20557. echo '% State ' . $state
  20558. . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n";
  20559. }
  20560. protected function traceRead($symbol): void {
  20561. echo '% Reading ' . $this->symbolToName[$symbol] . "\n";
  20562. }
  20563. protected function traceShift($symbol): void {
  20564. echo '% Shift ' . $this->symbolToName[$symbol] . "\n";
  20565. }
  20566. protected function traceAccept(): void {
  20567. echo "% Accepted.\n";
  20568. }
  20569. protected function traceReduce($n): void {
  20570. echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n";
  20571. }
  20572. protected function tracePop($state): void {
  20573. echo '% Recovering, uncovered state ' . $state . "\n";
  20574. }
  20575. protected function traceDiscard($symbol): void {
  20576. echo '% Discard ' . $this->symbolToName[$symbol] . "\n";
  20577. }
  20578. */
  20579. /*
  20580. * Helper functions invoked by semantic actions
  20581. */
  20582. /**
  20583. * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions.
  20584. *
  20585. * @param Node\Stmt[] $stmts
  20586. * @return Node\Stmt[]
  20587. */
  20588. protected function handleNamespaces(array $stmts): array
  20589. {
  20590. $hasErrored = \false;
  20591. $style = $this->getNamespacingStyle($stmts);
  20592. if (null === $style) {
  20593. // not namespaced, nothing to do
  20594. return $stmts;
  20595. }
  20596. if ('brace' === $style) {
  20597. // For braced namespaces we only have to check that there are no invalid statements between the namespaces
  20598. $afterFirstNamespace = \false;
  20599. foreach ($stmts as $stmt) {
  20600. if ($stmt instanceof Node\Stmt\Namespace_) {
  20601. $afterFirstNamespace = \true;
  20602. } elseif (!$stmt instanceof Node\Stmt\HaltCompiler && !$stmt instanceof Node\Stmt\Nop && $afterFirstNamespace && !$hasErrored) {
  20603. $this->emitError(new Error('No code may exist outside of namespace {}', $stmt->getAttributes()));
  20604. $hasErrored = \true;
  20605. // Avoid one error for every statement
  20606. }
  20607. }
  20608. return $stmts;
  20609. } else {
  20610. // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts
  20611. $resultStmts = [];
  20612. $targetStmts =& $resultStmts;
  20613. $lastNs = null;
  20614. foreach ($stmts as $stmt) {
  20615. if ($stmt instanceof Node\Stmt\Namespace_) {
  20616. if ($lastNs !== null) {
  20617. $this->fixupNamespaceAttributes($lastNs);
  20618. }
  20619. if ($stmt->stmts === null) {
  20620. $stmt->stmts = [];
  20621. $targetStmts =& $stmt->stmts;
  20622. $resultStmts[] = $stmt;
  20623. } else {
  20624. // This handles the invalid case of mixed style namespaces
  20625. $resultStmts[] = $stmt;
  20626. $targetStmts =& $resultStmts;
  20627. }
  20628. $lastNs = $stmt;
  20629. } elseif ($stmt instanceof Node\Stmt\HaltCompiler) {
  20630. // __halt_compiler() is not moved into the namespace
  20631. $resultStmts[] = $stmt;
  20632. } else {
  20633. $targetStmts[] = $stmt;
  20634. }
  20635. }
  20636. if ($lastNs !== null) {
  20637. $this->fixupNamespaceAttributes($lastNs);
  20638. }
  20639. return $resultStmts;
  20640. }
  20641. }
  20642. private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt): void
  20643. {
  20644. // We moved the statements into the namespace node, as such the end of the namespace node
  20645. // needs to be extended to the end of the statements.
  20646. if (empty($stmt->stmts)) {
  20647. return;
  20648. }
  20649. // We only move the builtin end attributes here. This is the best we can do with the
  20650. // knowledge we have.
  20651. $endAttributes = ['endLine', 'endFilePos', 'endTokenPos'];
  20652. $lastStmt = $stmt->stmts[count($stmt->stmts) - 1];
  20653. foreach ($endAttributes as $endAttribute) {
  20654. if ($lastStmt->hasAttribute($endAttribute)) {
  20655. $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute));
  20656. }
  20657. }
  20658. }
  20659. /** @return array<string, mixed> */
  20660. private function getNamespaceErrorAttributes(Namespace_ $node): array
  20661. {
  20662. $attrs = $node->getAttributes();
  20663. // Adjust end attributes to only cover the "namespace" keyword, not the whole namespace.
  20664. if (isset($attrs['startLine'])) {
  20665. $attrs['endLine'] = $attrs['startLine'];
  20666. }
  20667. if (isset($attrs['startTokenPos'])) {
  20668. $attrs['endTokenPos'] = $attrs['startTokenPos'];
  20669. }
  20670. if (isset($attrs['startFilePos'])) {
  20671. $attrs['endFilePos'] = $attrs['startFilePos'] + \strlen('namespace') - 1;
  20672. }
  20673. return $attrs;
  20674. }
  20675. /**
  20676. * Determine namespacing style (semicolon or brace)
  20677. *
  20678. * @param Node[] $stmts Top-level statements.
  20679. *
  20680. * @return null|string One of "semicolon", "brace" or null (no namespaces)
  20681. */
  20682. private function getNamespacingStyle(array $stmts): ?string
  20683. {
  20684. $style = null;
  20685. $hasNotAllowedStmts = \false;
  20686. foreach ($stmts as $i => $stmt) {
  20687. if ($stmt instanceof Node\Stmt\Namespace_) {
  20688. $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace';
  20689. if (null === $style) {
  20690. $style = $currentStyle;
  20691. if ($hasNotAllowedStmts) {
  20692. $this->emitError(new Error('Namespace declaration statement has to be the very first statement in the script', $this->getNamespaceErrorAttributes($stmt)));
  20693. }
  20694. } elseif ($style !== $currentStyle) {
  20695. $this->emitError(new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $this->getNamespaceErrorAttributes($stmt)));
  20696. // Treat like semicolon style for namespace normalization
  20697. return 'semicolon';
  20698. }
  20699. continue;
  20700. }
  20701. /* declare(), __halt_compiler() and nops can be used before a namespace declaration */
  20702. if ($stmt instanceof Node\Stmt\Declare_ || $stmt instanceof Node\Stmt\HaltCompiler || $stmt instanceof Node\Stmt\Nop) {
  20703. continue;
  20704. }
  20705. /* There may be a hashbang line at the very start of the file */
  20706. if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) {
  20707. continue;
  20708. }
  20709. /* Everything else if forbidden before namespace declarations */
  20710. $hasNotAllowedStmts = \true;
  20711. }
  20712. return $style;
  20713. }
  20714. /** @return Name|Identifier */
  20715. protected function handleBuiltinTypes(Name $name)
  20716. {
  20717. if (!$name->isUnqualified()) {
  20718. return $name;
  20719. }
  20720. $lowerName = $name->toLowerString();
  20721. if (!$this->phpVersion->supportsBuiltinType($lowerName)) {
  20722. return $name;
  20723. }
  20724. return new Node\Identifier($lowerName, $name->getAttributes());
  20725. }
  20726. /**
  20727. * Get combined start and end attributes at a stack location
  20728. *
  20729. * @param int $stackPos Stack location
  20730. *
  20731. * @return array<string, mixed> Combined start and end attributes
  20732. */
  20733. protected function getAttributesAt(int $stackPos): array
  20734. {
  20735. return $this->getAttributes($this->tokenStartStack[$stackPos], $this->tokenEndStack[$stackPos]);
  20736. }
  20737. protected function getFloatCastKind(string $cast): int
  20738. {
  20739. $cast = strtolower($cast);
  20740. if (strpos($cast, 'float') !== \false) {
  20741. return Double::KIND_FLOAT;
  20742. }
  20743. if (strpos($cast, 'real') !== \false) {
  20744. return Double::KIND_REAL;
  20745. }
  20746. return Double::KIND_DOUBLE;
  20747. }
  20748. /** @param array<string, mixed> $attributes */
  20749. protected function parseLNumber(string $str, array $attributes, bool $allowInvalidOctal = \false): Int_
  20750. {
  20751. try {
  20752. return Int_::fromString($str, $attributes, $allowInvalidOctal);
  20753. } catch (Error $error) {
  20754. $this->emitError($error);
  20755. // Use dummy value
  20756. return new Int_(0, $attributes);
  20757. }
  20758. }
  20759. /**
  20760. * Parse a T_NUM_STRING token into either an integer or string node.
  20761. *
  20762. * @param string $str Number string
  20763. * @param array<string, mixed> $attributes Attributes
  20764. *
  20765. * @return Int_|String_ Integer or string node.
  20766. */
  20767. protected function parseNumString(string $str, array $attributes)
  20768. {
  20769. if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) {
  20770. return new String_($str, $attributes);
  20771. }
  20772. $num = +$str;
  20773. if (!is_int($num)) {
  20774. return new String_($str, $attributes);
  20775. }
  20776. return new Int_($num, $attributes);
  20777. }
  20778. /** @param array<string, mixed> $attributes */
  20779. protected function stripIndentation(string $string, int $indentLen, string $indentChar, bool $newlineAtStart, bool $newlineAtEnd, array $attributes): string
  20780. {
  20781. if ($indentLen === 0) {
  20782. return $string;
  20783. }
  20784. $start = $newlineAtStart ? '(?:(?<=\n)|\A)' : '(?<=\n)';
  20785. $end = $newlineAtEnd ? '(?:(?=[\r\n])|\z)' : '(?=[\r\n])';
  20786. $regex = '/' . $start . '([ \t]*)(' . $end . ')?/';
  20787. return preg_replace_callback($regex, function ($matches) use ($indentLen, $indentChar, $attributes) {
  20788. $prefix = substr($matches[1], 0, $indentLen);
  20789. if (\false !== strpos($prefix, $indentChar === " " ? "\t" : " ")) {
  20790. $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $attributes));
  20791. } elseif (strlen($prefix) < $indentLen && !isset($matches[2])) {
  20792. $this->emitError(new Error('Invalid body indentation level ' . '(expecting an indentation level of at least ' . $indentLen . ')', $attributes));
  20793. }
  20794. return substr($matches[0], strlen($prefix));
  20795. }, $string);
  20796. }
  20797. /**
  20798. * @param string|(Expr|InterpolatedStringPart)[] $contents
  20799. * @param array<string, mixed> $attributes
  20800. * @param array<string, mixed> $endTokenAttributes
  20801. */
  20802. protected function parseDocString(string $startToken, $contents, string $endToken, array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape): Expr
  20803. {
  20804. $kind = strpos($startToken, "'") === \false ? String_::KIND_HEREDOC : String_::KIND_NOWDOC;
  20805. $regex = '/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/';
  20806. $result = preg_match($regex, $startToken, $matches);
  20807. assert($result === 1);
  20808. $label = $matches[1];
  20809. $result = preg_match('/\A[ \t]*/', $endToken, $matches);
  20810. assert($result === 1);
  20811. $indentation = $matches[0];
  20812. $attributes['kind'] = $kind;
  20813. $attributes['docLabel'] = $label;
  20814. $attributes['docIndentation'] = $indentation;
  20815. $indentHasSpaces = \false !== strpos($indentation, " ");
  20816. $indentHasTabs = \false !== strpos($indentation, "\t");
  20817. if ($indentHasSpaces && $indentHasTabs) {
  20818. $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $endTokenAttributes));
  20819. // Proceed processing as if this doc string is not indented
  20820. $indentation = '';
  20821. }
  20822. $indentLen = \strlen($indentation);
  20823. $indentChar = $indentHasSpaces ? " " : "\t";
  20824. if (\is_string($contents)) {
  20825. if ($contents === '') {
  20826. $attributes['rawValue'] = $contents;
  20827. return new String_('', $attributes);
  20828. }
  20829. $contents = $this->stripIndentation($contents, $indentLen, $indentChar, \true, \true, $attributes);
  20830. $contents = preg_replace('~(\r\n|\n|\r)\z~', '', $contents);
  20831. $attributes['rawValue'] = $contents;
  20832. if ($kind === String_::KIND_HEREDOC) {
  20833. $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape);
  20834. }
  20835. return new String_($contents, $attributes);
  20836. } else {
  20837. assert(count($contents) > 0);
  20838. if (!$contents[0] instanceof Node\InterpolatedStringPart) {
  20839. // If there is no leading encapsed string part, pretend there is an empty one
  20840. $this->stripIndentation('', $indentLen, $indentChar, \true, \false, $contents[0]->getAttributes());
  20841. }
  20842. $newContents = [];
  20843. foreach ($contents as $i => $part) {
  20844. if ($part instanceof Node\InterpolatedStringPart) {
  20845. $isLast = $i === \count($contents) - 1;
  20846. $part->value = $this->stripIndentation($part->value, $indentLen, $indentChar, $i === 0, $isLast, $part->getAttributes());
  20847. if ($isLast) {
  20848. $part->value = preg_replace('~(\r\n|\n|\r)\z~', '', $part->value);
  20849. }
  20850. $part->setAttribute('rawValue', $part->value);
  20851. $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape);
  20852. if ('' === $part->value) {
  20853. continue;
  20854. }
  20855. }
  20856. $newContents[] = $part;
  20857. }
  20858. return new InterpolatedString($newContents, $attributes);
  20859. }
  20860. }
  20861. protected function createCommentFromToken(Token $token, int $tokenPos): Comment
  20862. {
  20863. assert($token->id === \T_COMMENT || $token->id == \T_DOC_COMMENT);
  20864. return \T_DOC_COMMENT === $token->id ? new Comment\Doc($token->text, $token->line, $token->pos, $tokenPos, $token->getEndLine(), $token->getEndPos() - 1, $tokenPos) : new Comment($token->text, $token->line, $token->pos, $tokenPos, $token->getEndLine(), $token->getEndPos() - 1, $tokenPos);
  20865. }
  20866. /**
  20867. * Get last comment before the given token position, if any
  20868. */
  20869. protected function getCommentBeforeToken(int $tokenPos): ?Comment
  20870. {
  20871. while (--$tokenPos >= 0) {
  20872. $token = $this->tokens[$tokenPos];
  20873. if (!isset($this->dropTokens[$token->id])) {
  20874. break;
  20875. }
  20876. if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) {
  20877. return $this->createCommentFromToken($token, $tokenPos);
  20878. }
  20879. }
  20880. return null;
  20881. }
  20882. /**
  20883. * Create a zero-length nop to capture preceding comments, if any.
  20884. */
  20885. protected function maybeCreateZeroLengthNop(int $tokenPos): ?Nop
  20886. {
  20887. $comment = $this->getCommentBeforeToken($tokenPos);
  20888. if ($comment === null) {
  20889. return null;
  20890. }
  20891. $commentEndLine = $comment->getEndLine();
  20892. $commentEndFilePos = $comment->getEndFilePos();
  20893. $commentEndTokenPos = $comment->getEndTokenPos();
  20894. $attributes = ['startLine' => $commentEndLine, 'endLine' => $commentEndLine, 'startFilePos' => $commentEndFilePos + 1, 'endFilePos' => $commentEndFilePos, 'startTokenPos' => $commentEndTokenPos + 1, 'endTokenPos' => $commentEndTokenPos];
  20895. return new Nop($attributes);
  20896. }
  20897. protected function maybeCreateNop(int $tokenStartPos, int $tokenEndPos): ?Nop
  20898. {
  20899. if ($this->getCommentBeforeToken($tokenStartPos) === null) {
  20900. return null;
  20901. }
  20902. return new Nop($this->getAttributes($tokenStartPos, $tokenEndPos));
  20903. }
  20904. protected function handleHaltCompiler(): string
  20905. {
  20906. // Prevent the lexer from returning any further tokens.
  20907. $nextToken = $this->tokens[$this->tokenPos + 1];
  20908. $this->tokenPos = \count($this->tokens) - 2;
  20909. // Return text after __halt_compiler.
  20910. return $nextToken->id === \T_INLINE_HTML ? $nextToken->text : '';
  20911. }
  20912. protected function inlineHtmlHasLeadingNewline(int $stackPos): bool
  20913. {
  20914. $tokenPos = $this->tokenStartStack[$stackPos];
  20915. $token = $this->tokens[$tokenPos];
  20916. assert($token->id == \T_INLINE_HTML);
  20917. if ($tokenPos > 0) {
  20918. $prevToken = $this->tokens[$tokenPos - 1];
  20919. assert($prevToken->id == \T_CLOSE_TAG);
  20920. return \false !== strpos($prevToken->text, "\n") || \false !== strpos($prevToken->text, "\r");
  20921. }
  20922. return \true;
  20923. }
  20924. /**
  20925. * @return array<string, mixed>
  20926. */
  20927. protected function createEmptyElemAttributes(int $tokenPos): array
  20928. {
  20929. return $this->getAttributesForToken($tokenPos);
  20930. }
  20931. protected function fixupArrayDestructuring(Array_ $node): Expr\List_
  20932. {
  20933. $this->createdArrays->detach($node);
  20934. return new Expr\List_(array_map(function (Node\ArrayItem $item) {
  20935. if ($item->value instanceof Expr\Error) {
  20936. // We used Error as a placeholder for empty elements, which are legal for destructuring.
  20937. return null;
  20938. }
  20939. if ($item->value instanceof Array_) {
  20940. return new Node\ArrayItem($this->fixupArrayDestructuring($item->value), $item->key, $item->byRef, $item->getAttributes());
  20941. }
  20942. return $item;
  20943. }, $node->items), ['kind' => Expr\List_::KIND_ARRAY] + $node->getAttributes());
  20944. }
  20945. protected function postprocessList(Expr\List_ $node): void
  20946. {
  20947. foreach ($node->items as $i => $item) {
  20948. if ($item->value instanceof Expr\Error) {
  20949. // We used Error as a placeholder for empty elements, which are legal for destructuring.
  20950. $node->items[$i] = null;
  20951. }
  20952. }
  20953. }
  20954. /** @param ElseIf_|Else_ $node */
  20955. protected function fixupAlternativeElse($node): void
  20956. {
  20957. // Make sure a trailing nop statement carrying comments is part of the node.
  20958. $numStmts = \count($node->stmts);
  20959. if ($numStmts !== 0 && $node->stmts[$numStmts - 1] instanceof Nop) {
  20960. $nopAttrs = $node->stmts[$numStmts - 1]->getAttributes();
  20961. if (isset($nopAttrs['endLine'])) {
  20962. $node->setAttribute('endLine', $nopAttrs['endLine']);
  20963. }
  20964. if (isset($nopAttrs['endFilePos'])) {
  20965. $node->setAttribute('endFilePos', $nopAttrs['endFilePos']);
  20966. }
  20967. if (isset($nopAttrs['endTokenPos'])) {
  20968. $node->setAttribute('endTokenPos', $nopAttrs['endTokenPos']);
  20969. }
  20970. }
  20971. }
  20972. protected function checkClassModifier(int $a, int $b, int $modifierPos): void
  20973. {
  20974. try {
  20975. Modifiers::verifyClassModifier($a, $b);
  20976. } catch (Error $error) {
  20977. $error->setAttributes($this->getAttributesAt($modifierPos));
  20978. $this->emitError($error);
  20979. }
  20980. }
  20981. protected function checkModifier(int $a, int $b, int $modifierPos): void
  20982. {
  20983. // Jumping through some hoops here because verifyModifier() is also used elsewhere
  20984. try {
  20985. Modifiers::verifyModifier($a, $b);
  20986. } catch (Error $error) {
  20987. $error->setAttributes($this->getAttributesAt($modifierPos));
  20988. $this->emitError($error);
  20989. }
  20990. }
  20991. protected function checkParam(Param $node): void
  20992. {
  20993. if ($node->variadic && null !== $node->default) {
  20994. $this->emitError(new Error('Variadic parameter cannot have a default value', $node->default->getAttributes()));
  20995. }
  20996. }
  20997. protected function checkTryCatch(TryCatch $node): void
  20998. {
  20999. if (empty($node->catches) && null === $node->finally) {
  21000. $this->emitError(new Error('Cannot use try without catch or finally', $node->getAttributes()));
  21001. }
  21002. }
  21003. protected function checkNamespace(Namespace_ $node): void
  21004. {
  21005. if (null !== $node->stmts) {
  21006. foreach ($node->stmts as $stmt) {
  21007. if ($stmt instanceof Namespace_) {
  21008. $this->emitError(new Error('Namespace declarations cannot be nested', $stmt->getAttributes()));
  21009. }
  21010. }
  21011. }
  21012. }
  21013. private function checkClassName(?Identifier $name, int $namePos): void
  21014. {
  21015. if (null !== $name && $name->isSpecialClassName()) {
  21016. $this->emitError(new Error(sprintf('Cannot use \'%s\' as class name as it is reserved', $name), $this->getAttributesAt($namePos)));
  21017. }
  21018. }
  21019. /** @param Name[] $interfaces */
  21020. private function checkImplementedInterfaces(array $interfaces): void
  21021. {
  21022. foreach ($interfaces as $interface) {
  21023. if ($interface->isSpecialClassName()) {
  21024. $this->emitError(new Error(sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes()));
  21025. }
  21026. }
  21027. }
  21028. protected function checkClass(Class_ $node, int $namePos): void
  21029. {
  21030. $this->checkClassName($node->name, $namePos);
  21031. if ($node->extends && $node->extends->isSpecialClassName()) {
  21032. $this->emitError(new Error(sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), $node->extends->getAttributes()));
  21033. }
  21034. $this->checkImplementedInterfaces($node->implements);
  21035. }
  21036. protected function checkInterface(Interface_ $node, int $namePos): void
  21037. {
  21038. $this->checkClassName($node->name, $namePos);
  21039. $this->checkImplementedInterfaces($node->extends);
  21040. }
  21041. protected function checkEnum(Enum_ $node, int $namePos): void
  21042. {
  21043. $this->checkClassName($node->name, $namePos);
  21044. $this->checkImplementedInterfaces($node->implements);
  21045. }
  21046. protected function checkClassMethod(ClassMethod $node, int $modifierPos): void
  21047. {
  21048. if ($node->flags & Modifiers::STATIC) {
  21049. switch ($node->name->toLowerString()) {
  21050. case '__construct':
  21051. $this->emitError(new Error(sprintf('Constructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
  21052. break;
  21053. case '__destruct':
  21054. $this->emitError(new Error(sprintf('Destructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
  21055. break;
  21056. case '__clone':
  21057. $this->emitError(new Error(sprintf('Clone method %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
  21058. break;
  21059. }
  21060. }
  21061. if ($node->flags & Modifiers::READONLY) {
  21062. $this->emitError(new Error(sprintf('Method %s() cannot be readonly', $node->name), $this->getAttributesAt($modifierPos)));
  21063. }
  21064. }
  21065. protected function checkClassConst(ClassConst $node, int $modifierPos): void
  21066. {
  21067. foreach ([Modifiers::STATIC, Modifiers::ABSTRACT, Modifiers::READONLY] as $modifier) {
  21068. if ($node->flags & $modifier) {
  21069. $this->emitError(new Error("Cannot use '" . Modifiers::toString($modifier) . "' as constant modifier", $this->getAttributesAt($modifierPos)));
  21070. }
  21071. }
  21072. }
  21073. protected function checkUseUse(UseItem $node, int $namePos): void
  21074. {
  21075. if ($node->alias && $node->alias->isSpecialClassName()) {
  21076. $this->emitError(new Error(sprintf('Cannot use %s as %s because \'%2$s\' is a special class name', $node->name, $node->alias), $this->getAttributesAt($namePos)));
  21077. }
  21078. }
  21079. /** @param PropertyHook[] $hooks */
  21080. protected function checkPropertyHookList(array $hooks, int $hookPos): void
  21081. {
  21082. if (empty($hooks)) {
  21083. $this->emitError(new Error('Property hook list cannot be empty', $this->getAttributesAt($hookPos)));
  21084. }
  21085. }
  21086. protected function checkPropertyHook(PropertyHook $hook, ?int $paramListPos): void
  21087. {
  21088. $name = $hook->name->toLowerString();
  21089. if ($name !== 'get' && $name !== 'set') {
  21090. $this->emitError(new Error('Unknown hook "' . $hook->name . '", expected "get" or "set"', $hook->name->getAttributes()));
  21091. }
  21092. if ($name === 'get' && $paramListPos !== null) {
  21093. $this->emitError(new Error('get hook must not have a parameter list', $this->getAttributesAt($paramListPos)));
  21094. }
  21095. }
  21096. protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos): void
  21097. {
  21098. try {
  21099. Modifiers::verifyModifier($a, $b);
  21100. } catch (Error $error) {
  21101. $error->setAttributes($this->getAttributesAt($modifierPos));
  21102. $this->emitError($error);
  21103. }
  21104. if ($b != Modifiers::FINAL) {
  21105. $this->emitError(new Error('Cannot use the ' . Modifiers::toString($b) . ' modifier on a property hook', $this->getAttributesAt($modifierPos)));
  21106. }
  21107. }
  21108. /** @param array<Node\Arg|Node\VariadicPlaceholder> $args */
  21109. private function isSimpleExit(array $args): bool
  21110. {
  21111. if (\count($args) === 0) {
  21112. return \true;
  21113. }
  21114. if (\count($args) === 1) {
  21115. $arg = $args[0];
  21116. return $arg instanceof Arg && $arg->name === null && $arg->byRef === \false && $arg->unpack === \false;
  21117. }
  21118. return \false;
  21119. }
  21120. /**
  21121. * @param array<Node\Arg|Node\VariadicPlaceholder> $args
  21122. * @param array<string, mixed> $attrs
  21123. */
  21124. protected function createExitExpr(string $name, int $namePos, array $args, array $attrs): Expr
  21125. {
  21126. if ($this->isSimpleExit($args)) {
  21127. // Create Exit node for backwards compatibility.
  21128. $attrs['kind'] = strtolower($name) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
  21129. return new Expr\Exit_(\count($args) === 1 ? $args[0]->value : null, $attrs);
  21130. }
  21131. return new Expr\FuncCall(new Name($name, $this->getAttributesAt($namePos)), $args, $attrs);
  21132. }
  21133. /**
  21134. * Creates the token map.
  21135. *
  21136. * The token map maps the PHP internal token identifiers
  21137. * to the identifiers used by the Parser. Additionally it
  21138. * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'.
  21139. *
  21140. * @return array<int, int> The token map
  21141. */
  21142. protected function createTokenMap(): array
  21143. {
  21144. $tokenMap = [];
  21145. // Single-char tokens use an identity mapping.
  21146. for ($i = 0; $i < 256; ++$i) {
  21147. $tokenMap[$i] = $i;
  21148. }
  21149. foreach ($this->symbolToName as $name) {
  21150. if ($name[0] === 'T') {
  21151. $tokenMap[\constant($name)] = constant(static::class . '::' . $name);
  21152. }
  21153. }
  21154. // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
  21155. $tokenMap[\T_OPEN_TAG_WITH_ECHO] = static::T_ECHO;
  21156. // T_CLOSE_TAG is equivalent to ';'
  21157. $tokenMap[\T_CLOSE_TAG] = ord(';');
  21158. // We have created a map from PHP token IDs to external symbol IDs.
  21159. // Now map them to the internal symbol ID.
  21160. $fullTokenMap = [];
  21161. foreach ($tokenMap as $phpToken => $extSymbol) {
  21162. $intSymbol = $this->tokenToSymbol[$extSymbol];
  21163. if ($intSymbol === $this->invalidSymbol) {
  21164. continue;
  21165. }
  21166. $fullTokenMap[$phpToken] = $intSymbol;
  21167. }
  21168. return $fullTokenMap;
  21169. }
  21170. }
  21171. <?php
  21172. declare (strict_types=1);
  21173. namespace PHPUnitPHAR\PhpParser;
  21174. use PHPUnitPHAR\PhpParser\Parser\Php7;
  21175. use PHPUnitPHAR\PhpParser\Parser\Php8;
  21176. class ParserFactory
  21177. {
  21178. /**
  21179. * Create a parser targeting the given version on a best-effort basis. The parser will generally
  21180. * accept code for the newest supported version, but will try to accommodate code that becomes
  21181. * invalid in newer versions or changes in interpretation.
  21182. */
  21183. public function createForVersion(PhpVersion $version): Parser
  21184. {
  21185. if ($version->isHostVersion()) {
  21186. $lexer = new Lexer();
  21187. } else {
  21188. $lexer = new Lexer\Emulative($version);
  21189. }
  21190. if ($version->id >= 80000) {
  21191. return new Php8($lexer, $version);
  21192. }
  21193. return new Php7($lexer, $version);
  21194. }
  21195. /**
  21196. * Create a parser targeting the newest version supported by this library. Code for older
  21197. * versions will be accepted if there have been no relevant backwards-compatibility breaks in
  21198. * PHP.
  21199. */
  21200. public function createForNewestSupportedVersion(): Parser
  21201. {
  21202. return $this->createForVersion(PhpVersion::getNewestSupported());
  21203. }
  21204. /**
  21205. * Create a parser targeting the host PHP version, that is the PHP version we're currently
  21206. * running on. This parser will not use any token emulation.
  21207. */
  21208. public function createForHostVersion(): Parser
  21209. {
  21210. return $this->createForVersion(PhpVersion::getHostVersion());
  21211. }
  21212. }
  21213. <?php
  21214. declare (strict_types=1);
  21215. namespace PHPUnitPHAR\PhpParser;
  21216. /**
  21217. * A PHP version, representing only the major and minor version components.
  21218. */
  21219. class PhpVersion
  21220. {
  21221. /** @var int Version ID in PHP_VERSION_ID format */
  21222. public int $id;
  21223. /** @var int[] Minimum versions for builtin types */
  21224. private const BUILTIN_TYPE_VERSIONS = ['array' => 50100, 'callable' => 50400, 'bool' => 70000, 'int' => 70000, 'float' => 70000, 'string' => 70000, 'iterable' => 70100, 'void' => 70100, 'object' => 70200, 'null' => 80000, 'false' => 80000, 'mixed' => 80000, 'never' => 80100, 'true' => 80200];
  21225. private function __construct(int $id)
  21226. {
  21227. $this->id = $id;
  21228. }
  21229. /**
  21230. * Create a PhpVersion object from major and minor version components.
  21231. */
  21232. public static function fromComponents(int $major, int $minor): self
  21233. {
  21234. return new self($major * 10000 + $minor * 100);
  21235. }
  21236. /**
  21237. * Get the newest PHP version supported by this library. Support for this version may be partial,
  21238. * if it is still under development.
  21239. */
  21240. public static function getNewestSupported(): self
  21241. {
  21242. return self::fromComponents(8, 4);
  21243. }
  21244. /**
  21245. * Get the host PHP version, that is the PHP version we're currently running on.
  21246. */
  21247. public static function getHostVersion(): self
  21248. {
  21249. return self::fromComponents(\PHP_MAJOR_VERSION, \PHP_MINOR_VERSION);
  21250. }
  21251. /**
  21252. * Parse the version from a string like "8.1".
  21253. */
  21254. public static function fromString(string $version): self
  21255. {
  21256. if (!preg_match('/^(\d+)\.(\d+)/', $version, $matches)) {
  21257. throw new \LogicException("Invalid PHP version \"{$version}\"");
  21258. }
  21259. return self::fromComponents((int) $matches[1], (int) $matches[2]);
  21260. }
  21261. /**
  21262. * Check whether two versions are the same.
  21263. */
  21264. public function equals(PhpVersion $other): bool
  21265. {
  21266. return $this->id === $other->id;
  21267. }
  21268. /**
  21269. * Check whether this version is greater than or equal to the argument.
  21270. */
  21271. public function newerOrEqual(PhpVersion $other): bool
  21272. {
  21273. return $this->id >= $other->id;
  21274. }
  21275. /**
  21276. * Check whether this version is older than the argument.
  21277. */
  21278. public function older(PhpVersion $other): bool
  21279. {
  21280. return $this->id < $other->id;
  21281. }
  21282. /**
  21283. * Check whether this is the host PHP version.
  21284. */
  21285. public function isHostVersion(): bool
  21286. {
  21287. return $this->equals(self::getHostVersion());
  21288. }
  21289. /**
  21290. * Check whether this PHP version supports the given builtin type. Type name must be lowercase.
  21291. */
  21292. public function supportsBuiltinType(string $type): bool
  21293. {
  21294. $minVersion = self::BUILTIN_TYPE_VERSIONS[$type] ?? null;
  21295. return $minVersion !== null && $this->id >= $minVersion;
  21296. }
  21297. /**
  21298. * Whether this version supports [] array literals.
  21299. */
  21300. public function supportsShortArraySyntax(): bool
  21301. {
  21302. return $this->id >= 50400;
  21303. }
  21304. /**
  21305. * Whether this version supports [] for destructuring.
  21306. */
  21307. public function supportsShortArrayDestructuring(): bool
  21308. {
  21309. return $this->id >= 70100;
  21310. }
  21311. /**
  21312. * Whether this version supports flexible heredoc/nowdoc.
  21313. */
  21314. public function supportsFlexibleHeredoc(): bool
  21315. {
  21316. return $this->id >= 70300;
  21317. }
  21318. /**
  21319. * Whether this version supports trailing commas in parameter lists.
  21320. */
  21321. public function supportsTrailingCommaInParamList(): bool
  21322. {
  21323. return $this->id >= 80000;
  21324. }
  21325. /**
  21326. * Whether this version allows "$var =& new Obj".
  21327. */
  21328. public function allowsAssignNewByReference(): bool
  21329. {
  21330. return $this->id < 70000;
  21331. }
  21332. /**
  21333. * Whether this version allows invalid octals like "08".
  21334. */
  21335. public function allowsInvalidOctals(): bool
  21336. {
  21337. return $this->id < 70000;
  21338. }
  21339. /**
  21340. * Whether this version allows DEL (\x7f) to occur in identifiers.
  21341. */
  21342. public function allowsDelInIdentifiers(): bool
  21343. {
  21344. return $this->id < 70100;
  21345. }
  21346. /**
  21347. * Whether this version supports yield in expression context without parentheses.
  21348. */
  21349. public function supportsYieldWithoutParentheses(): bool
  21350. {
  21351. return $this->id >= 70000;
  21352. }
  21353. /**
  21354. * Whether this version supports unicode escape sequences in strings.
  21355. */
  21356. public function supportsUnicodeEscapes(): bool
  21357. {
  21358. return $this->id >= 70000;
  21359. }
  21360. }
  21361. <?php
  21362. declare (strict_types=1);
  21363. namespace PHPUnitPHAR\PhpParser;
  21364. use PHPUnitPHAR\PhpParser\Node\Expr;
  21365. interface PrettyPrinter
  21366. {
  21367. /**
  21368. * Pretty prints an array of statements.
  21369. *
  21370. * @param Node[] $stmts Array of statements
  21371. *
  21372. * @return string Pretty printed statements
  21373. */
  21374. public function prettyPrint(array $stmts): string;
  21375. /**
  21376. * Pretty prints an expression.
  21377. *
  21378. * @param Expr $node Expression node
  21379. *
  21380. * @return string Pretty printed node
  21381. */
  21382. public function prettyPrintExpr(Expr $node): string;
  21383. /**
  21384. * Pretty prints a file of statements (includes the opening <?php tag if it is required).
  21385. *
  21386. * @param Node[] $stmts Array of statements
  21387. *
  21388. * @return string Pretty printed statements
  21389. */
  21390. public function prettyPrintFile(array $stmts): string;
  21391. /**
  21392. * Perform a format-preserving pretty print of an AST.
  21393. *
  21394. * The format preservation is best effort. For some changes to the AST the formatting will not
  21395. * be preserved (at least not locally).
  21396. *
  21397. * In order to use this method a number of prerequisites must be satisfied:
  21398. * * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
  21399. * * The CloningVisitor must be run on the AST prior to modification.
  21400. * * The original tokens must be provided, using the getTokens() method on the lexer.
  21401. *
  21402. * @param Node[] $stmts Modified AST with links to original AST
  21403. * @param Node[] $origStmts Original AST with token offset information
  21404. * @param Token[] $origTokens Tokens of the original code
  21405. */
  21406. public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string;
  21407. }
  21408. <?php
  21409. declare (strict_types=1);
  21410. namespace PHPUnitPHAR\PhpParser\PrettyPrinter;
  21411. use PHPUnitPHAR\PhpParser\Node;
  21412. use PHPUnitPHAR\PhpParser\Node\Expr;
  21413. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  21414. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  21415. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  21416. use PHPUnitPHAR\PhpParser\Node\Name;
  21417. use PHPUnitPHAR\PhpParser\Node\Scalar;
  21418. use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
  21419. use PHPUnitPHAR\PhpParser\Node\Stmt;
  21420. use PHPUnitPHAR\PhpParser\PrettyPrinterAbstract;
  21421. class Standard extends PrettyPrinterAbstract
  21422. {
  21423. // Special nodes
  21424. protected function pParam(Node\Param $node): string
  21425. {
  21426. return $this->pAttrGroups($node->attrGroups, \true) . $this->pModifiers($node->flags) . ($node->type ? $this->p($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') . $this->p($node->var) . ($node->default ? ' = ' . $this->p($node->default) : '') . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : '');
  21427. }
  21428. protected function pArg(Node\Arg $node): string
  21429. {
  21430. return ($node->name ? $node->name->toString() . ': ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
  21431. }
  21432. protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node): string
  21433. {
  21434. return '...';
  21435. }
  21436. protected function pConst(Node\Const_ $node): string
  21437. {
  21438. return $node->name . ' = ' . $this->p($node->value);
  21439. }
  21440. protected function pNullableType(Node\NullableType $node): string
  21441. {
  21442. return '?' . $this->p($node->type);
  21443. }
  21444. protected function pUnionType(Node\UnionType $node): string
  21445. {
  21446. $types = [];
  21447. foreach ($node->types as $typeNode) {
  21448. if ($typeNode instanceof Node\IntersectionType) {
  21449. $types[] = '(' . $this->p($typeNode) . ')';
  21450. continue;
  21451. }
  21452. $types[] = $this->p($typeNode);
  21453. }
  21454. return implode('|', $types);
  21455. }
  21456. protected function pIntersectionType(Node\IntersectionType $node): string
  21457. {
  21458. return $this->pImplode($node->types, '&');
  21459. }
  21460. protected function pIdentifier(Node\Identifier $node): string
  21461. {
  21462. return $node->name;
  21463. }
  21464. protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node): string
  21465. {
  21466. return '$' . $node->name;
  21467. }
  21468. protected function pAttribute(Node\Attribute $node): string
  21469. {
  21470. return $this->p($node->name) . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : '');
  21471. }
  21472. protected function pAttributeGroup(Node\AttributeGroup $node): string
  21473. {
  21474. return '#[' . $this->pCommaSeparated($node->attrs) . ']';
  21475. }
  21476. // Names
  21477. protected function pName(Name $node): string
  21478. {
  21479. return $node->name;
  21480. }
  21481. protected function pName_FullyQualified(Name\FullyQualified $node): string
  21482. {
  21483. return '\\' . $node->name;
  21484. }
  21485. protected function pName_Relative(Name\Relative $node): string
  21486. {
  21487. return 'namespace\\' . $node->name;
  21488. }
  21489. // Magic Constants
  21490. protected function pScalar_MagicConst_Class(MagicConst\Class_ $node): string
  21491. {
  21492. return '__CLASS__';
  21493. }
  21494. protected function pScalar_MagicConst_Dir(MagicConst\Dir $node): string
  21495. {
  21496. return '__DIR__';
  21497. }
  21498. protected function pScalar_MagicConst_File(MagicConst\File $node): string
  21499. {
  21500. return '__FILE__';
  21501. }
  21502. protected function pScalar_MagicConst_Function(MagicConst\Function_ $node): string
  21503. {
  21504. return '__FUNCTION__';
  21505. }
  21506. protected function pScalar_MagicConst_Line(MagicConst\Line $node): string
  21507. {
  21508. return '__LINE__';
  21509. }
  21510. protected function pScalar_MagicConst_Method(MagicConst\Method $node): string
  21511. {
  21512. return '__METHOD__';
  21513. }
  21514. protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node): string
  21515. {
  21516. return '__NAMESPACE__';
  21517. }
  21518. protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node): string
  21519. {
  21520. return '__TRAIT__';
  21521. }
  21522. protected function pScalar_MagicConst_Property(MagicConst\Property $node): string
  21523. {
  21524. return '__PROPERTY__';
  21525. }
  21526. // Scalars
  21527. private function indentString(string $str): string
  21528. {
  21529. return str_replace("\n", $this->nl, $str);
  21530. }
  21531. protected function pScalar_String(Scalar\String_ $node): string
  21532. {
  21533. $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED);
  21534. switch ($kind) {
  21535. case Scalar\String_::KIND_NOWDOC:
  21536. $label = $node->getAttribute('docLabel');
  21537. if ($label && !$this->containsEndLabel($node->value, $label)) {
  21538. $shouldIdent = $this->phpVersion->supportsFlexibleHeredoc();
  21539. $nl = $shouldIdent ? $this->nl : $this->newline;
  21540. if ($node->value === '') {
  21541. return "<<<'{$label}'{$nl}{$label}{$this->docStringEndToken}";
  21542. }
  21543. // Make sure trailing \r is not combined with following \n into CRLF.
  21544. if ($node->value[strlen($node->value) - 1] !== "\r") {
  21545. $value = $shouldIdent ? $this->indentString($node->value) : $node->value;
  21546. return "<<<'{$label}'{$nl}{$value}{$nl}{$label}{$this->docStringEndToken}";
  21547. }
  21548. }
  21549. /* break missing intentionally */
  21550. // no break
  21551. case Scalar\String_::KIND_SINGLE_QUOTED:
  21552. return $this->pSingleQuotedString($node->value);
  21553. case Scalar\String_::KIND_HEREDOC:
  21554. $label = $node->getAttribute('docLabel');
  21555. $escaped = $this->escapeString($node->value, null);
  21556. if ($label && !$this->containsEndLabel($escaped, $label)) {
  21557. $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
  21558. if ($escaped === '') {
  21559. return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}";
  21560. }
  21561. return "<<<{$label}{$nl}{$escaped}{$nl}{$label}{$this->docStringEndToken}";
  21562. }
  21563. /* break missing intentionally */
  21564. // no break
  21565. case Scalar\String_::KIND_DOUBLE_QUOTED:
  21566. return '"' . $this->escapeString($node->value, '"') . '"';
  21567. }
  21568. throw new \Exception('Invalid string kind');
  21569. }
  21570. protected function pScalar_InterpolatedString(Scalar\InterpolatedString $node): string
  21571. {
  21572. if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) {
  21573. $label = $node->getAttribute('docLabel');
  21574. if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) {
  21575. $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
  21576. if (count($node->parts) === 1 && $node->parts[0] instanceof Node\InterpolatedStringPart && $node->parts[0]->value === '') {
  21577. return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}";
  21578. }
  21579. return "<<<{$label}{$nl}" . $this->pEncapsList($node->parts, null) . "{$nl}{$label}{$this->docStringEndToken}";
  21580. }
  21581. }
  21582. return '"' . $this->pEncapsList($node->parts, '"') . '"';
  21583. }
  21584. protected function pScalar_Int(Scalar\Int_ $node): string
  21585. {
  21586. if ($node->value === -\PHP_INT_MAX - 1) {
  21587. // PHP_INT_MIN cannot be represented as a literal,
  21588. // because the sign is not part of the literal
  21589. return '(-' . \PHP_INT_MAX . '-1)';
  21590. }
  21591. $kind = $node->getAttribute('kind', Scalar\Int_::KIND_DEC);
  21592. if (Scalar\Int_::KIND_DEC === $kind) {
  21593. return (string) $node->value;
  21594. }
  21595. if ($node->value < 0) {
  21596. $sign = '-';
  21597. $str = (string) -$node->value;
  21598. } else {
  21599. $sign = '';
  21600. $str = (string) $node->value;
  21601. }
  21602. switch ($kind) {
  21603. case Scalar\Int_::KIND_BIN:
  21604. return $sign . '0b' . base_convert($str, 10, 2);
  21605. case Scalar\Int_::KIND_OCT:
  21606. return $sign . '0' . base_convert($str, 10, 8);
  21607. case Scalar\Int_::KIND_HEX:
  21608. return $sign . '0x' . base_convert($str, 10, 16);
  21609. }
  21610. throw new \Exception('Invalid number kind');
  21611. }
  21612. protected function pScalar_Float(Scalar\Float_ $node): string
  21613. {
  21614. if (!is_finite($node->value)) {
  21615. if ($node->value === \INF) {
  21616. return '1.0E+1000';
  21617. }
  21618. if ($node->value === -\INF) {
  21619. return '-1.0E+1000';
  21620. } else {
  21621. return '\NAN';
  21622. }
  21623. }
  21624. // Try to find a short full-precision representation
  21625. $stringValue = sprintf('%.16G', $node->value);
  21626. if ($node->value !== (float) $stringValue) {
  21627. $stringValue = sprintf('%.17G', $node->value);
  21628. }
  21629. // %G is locale dependent and there exists no locale-independent alternative. We don't want
  21630. // mess with switching locales here, so let's assume that a comma is the only non-standard
  21631. // decimal separator we may encounter...
  21632. $stringValue = str_replace(',', '.', $stringValue);
  21633. // ensure that number is really printed as float
  21634. return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue;
  21635. }
  21636. // Assignments
  21637. protected function pExpr_Assign(Expr\Assign $node, int $precedence, int $lhsPrecedence): string
  21638. {
  21639. return $this->pPrefixOp(Expr\Assign::class, $this->p($node->var) . ' = ', $node->expr, $precedence, $lhsPrecedence);
  21640. }
  21641. protected function pExpr_AssignRef(Expr\AssignRef $node, int $precedence, int $lhsPrecedence): string
  21642. {
  21643. return $this->pPrefixOp(Expr\AssignRef::class, $this->p($node->var) . ' =& ', $node->expr, $precedence, $lhsPrecedence);
  21644. }
  21645. protected function pExpr_AssignOp_Plus(AssignOp\Plus $node, int $precedence, int $lhsPrecedence): string
  21646. {
  21647. return $this->pPrefixOp(AssignOp\Plus::class, $this->p($node->var) . ' += ', $node->expr, $precedence, $lhsPrecedence);
  21648. }
  21649. protected function pExpr_AssignOp_Minus(AssignOp\Minus $node, int $precedence, int $lhsPrecedence): string
  21650. {
  21651. return $this->pPrefixOp(AssignOp\Minus::class, $this->p($node->var) . ' -= ', $node->expr, $precedence, $lhsPrecedence);
  21652. }
  21653. protected function pExpr_AssignOp_Mul(AssignOp\Mul $node, int $precedence, int $lhsPrecedence): string
  21654. {
  21655. return $this->pPrefixOp(AssignOp\Mul::class, $this->p($node->var) . ' *= ', $node->expr, $precedence, $lhsPrecedence);
  21656. }
  21657. protected function pExpr_AssignOp_Div(AssignOp\Div $node, int $precedence, int $lhsPrecedence): string
  21658. {
  21659. return $this->pPrefixOp(AssignOp\Div::class, $this->p($node->var) . ' /= ', $node->expr, $precedence, $lhsPrecedence);
  21660. }
  21661. protected function pExpr_AssignOp_Concat(AssignOp\Concat $node, int $precedence, int $lhsPrecedence): string
  21662. {
  21663. return $this->pPrefixOp(AssignOp\Concat::class, $this->p($node->var) . ' .= ', $node->expr, $precedence, $lhsPrecedence);
  21664. }
  21665. protected function pExpr_AssignOp_Mod(AssignOp\Mod $node, int $precedence, int $lhsPrecedence): string
  21666. {
  21667. return $this->pPrefixOp(AssignOp\Mod::class, $this->p($node->var) . ' %= ', $node->expr, $precedence, $lhsPrecedence);
  21668. }
  21669. protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string
  21670. {
  21671. return $this->pPrefixOp(AssignOp\BitwiseAnd::class, $this->p($node->var) . ' &= ', $node->expr, $precedence, $lhsPrecedence);
  21672. }
  21673. protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string
  21674. {
  21675. return $this->pPrefixOp(AssignOp\BitwiseOr::class, $this->p($node->var) . ' |= ', $node->expr, $precedence, $lhsPrecedence);
  21676. }
  21677. protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string
  21678. {
  21679. return $this->pPrefixOp(AssignOp\BitwiseXor::class, $this->p($node->var) . ' ^= ', $node->expr, $precedence, $lhsPrecedence);
  21680. }
  21681. protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string
  21682. {
  21683. return $this->pPrefixOp(AssignOp\ShiftLeft::class, $this->p($node->var) . ' <<= ', $node->expr, $precedence, $lhsPrecedence);
  21684. }
  21685. protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string
  21686. {
  21687. return $this->pPrefixOp(AssignOp\ShiftRight::class, $this->p($node->var) . ' >>= ', $node->expr, $precedence, $lhsPrecedence);
  21688. }
  21689. protected function pExpr_AssignOp_Pow(AssignOp\Pow $node, int $precedence, int $lhsPrecedence): string
  21690. {
  21691. return $this->pPrefixOp(AssignOp\Pow::class, $this->p($node->var) . ' **= ', $node->expr, $precedence, $lhsPrecedence);
  21692. }
  21693. protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node, int $precedence, int $lhsPrecedence): string
  21694. {
  21695. return $this->pPrefixOp(AssignOp\Coalesce::class, $this->p($node->var) . ' ??= ', $node->expr, $precedence, $lhsPrecedence);
  21696. }
  21697. // Binary expressions
  21698. protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node, int $precedence, int $lhsPrecedence): string
  21699. {
  21700. return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right, $precedence, $lhsPrecedence);
  21701. }
  21702. protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node, int $precedence, int $lhsPrecedence): string
  21703. {
  21704. return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right, $precedence, $lhsPrecedence);
  21705. }
  21706. protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node, int $precedence, int $lhsPrecedence): string
  21707. {
  21708. return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right, $precedence, $lhsPrecedence);
  21709. }
  21710. protected function pExpr_BinaryOp_Div(BinaryOp\Div $node, int $precedence, int $lhsPrecedence): string
  21711. {
  21712. return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right, $precedence, $lhsPrecedence);
  21713. }
  21714. protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node, int $precedence, int $lhsPrecedence): string
  21715. {
  21716. return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right, $precedence, $lhsPrecedence);
  21717. }
  21718. protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node, int $precedence, int $lhsPrecedence): string
  21719. {
  21720. return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right, $precedence, $lhsPrecedence);
  21721. }
  21722. protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node, int $precedence, int $lhsPrecedence): string
  21723. {
  21724. return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right, $precedence, $lhsPrecedence);
  21725. }
  21726. protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node, int $precedence, int $lhsPrecedence): string
  21727. {
  21728. return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right, $precedence, $lhsPrecedence);
  21729. }
  21730. protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string
  21731. {
  21732. return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right, $precedence, $lhsPrecedence);
  21733. }
  21734. protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string
  21735. {
  21736. return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right, $precedence, $lhsPrecedence);
  21737. }
  21738. protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string
  21739. {
  21740. return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right, $precedence, $lhsPrecedence);
  21741. }
  21742. protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string
  21743. {
  21744. return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right, $precedence, $lhsPrecedence);
  21745. }
  21746. protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string
  21747. {
  21748. return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right, $precedence, $lhsPrecedence);
  21749. }
  21750. protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node, int $precedence, int $lhsPrecedence): string
  21751. {
  21752. return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right, $precedence, $lhsPrecedence);
  21753. }
  21754. protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node, int $precedence, int $lhsPrecedence): string
  21755. {
  21756. return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right, $precedence, $lhsPrecedence);
  21757. }
  21758. protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node, int $precedence, int $lhsPrecedence): string
  21759. {
  21760. return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right, $precedence, $lhsPrecedence);
  21761. }
  21762. protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node, int $precedence, int $lhsPrecedence): string
  21763. {
  21764. return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right, $precedence, $lhsPrecedence);
  21765. }
  21766. protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node, int $precedence, int $lhsPrecedence): string
  21767. {
  21768. return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right, $precedence, $lhsPrecedence);
  21769. }
  21770. protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node, int $precedence, int $lhsPrecedence): string
  21771. {
  21772. return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right, $precedence, $lhsPrecedence);
  21773. }
  21774. protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node, int $precedence, int $lhsPrecedence): string
  21775. {
  21776. return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right, $precedence, $lhsPrecedence);
  21777. }
  21778. protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node, int $precedence, int $lhsPrecedence): string
  21779. {
  21780. return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right, $precedence, $lhsPrecedence);
  21781. }
  21782. protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node, int $precedence, int $lhsPrecedence): string
  21783. {
  21784. return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right, $precedence, $lhsPrecedence);
  21785. }
  21786. protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node, int $precedence, int $lhsPrecedence): string
  21787. {
  21788. return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right, $precedence, $lhsPrecedence);
  21789. }
  21790. protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node, int $precedence, int $lhsPrecedence): string
  21791. {
  21792. return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right, $precedence, $lhsPrecedence);
  21793. }
  21794. protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node, int $precedence, int $lhsPrecedence): string
  21795. {
  21796. return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right, $precedence, $lhsPrecedence);
  21797. }
  21798. protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node, int $precedence, int $lhsPrecedence): string
  21799. {
  21800. return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right, $precedence, $lhsPrecedence);
  21801. }
  21802. protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node, int $precedence, int $lhsPrecedence): string
  21803. {
  21804. return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right, $precedence, $lhsPrecedence);
  21805. }
  21806. protected function pExpr_Instanceof(Expr\Instanceof_ $node, int $precedence, int $lhsPrecedence): string
  21807. {
  21808. return $this->pPostfixOp(Expr\Instanceof_::class, $node->expr, ' instanceof ' . $this->pNewOperand($node->class), $precedence, $lhsPrecedence);
  21809. }
  21810. // Unary expressions
  21811. protected function pExpr_BooleanNot(Expr\BooleanNot $node, int $precedence, int $lhsPrecedence): string
  21812. {
  21813. return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr, $precedence, $lhsPrecedence);
  21814. }
  21815. protected function pExpr_BitwiseNot(Expr\BitwiseNot $node, int $precedence, int $lhsPrecedence): string
  21816. {
  21817. return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr, $precedence, $lhsPrecedence);
  21818. }
  21819. protected function pExpr_UnaryMinus(Expr\UnaryMinus $node, int $precedence, int $lhsPrecedence): string
  21820. {
  21821. return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr, $precedence, $lhsPrecedence);
  21822. }
  21823. protected function pExpr_UnaryPlus(Expr\UnaryPlus $node, int $precedence, int $lhsPrecedence): string
  21824. {
  21825. return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr, $precedence, $lhsPrecedence);
  21826. }
  21827. protected function pExpr_PreInc(Expr\PreInc $node): string
  21828. {
  21829. return '++' . $this->p($node->var);
  21830. }
  21831. protected function pExpr_PreDec(Expr\PreDec $node): string
  21832. {
  21833. return '--' . $this->p($node->var);
  21834. }
  21835. protected function pExpr_PostInc(Expr\PostInc $node): string
  21836. {
  21837. return $this->p($node->var) . '++';
  21838. }
  21839. protected function pExpr_PostDec(Expr\PostDec $node): string
  21840. {
  21841. return $this->p($node->var) . '--';
  21842. }
  21843. protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node, int $precedence, int $lhsPrecedence): string
  21844. {
  21845. return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr, $precedence, $lhsPrecedence);
  21846. }
  21847. protected function pExpr_YieldFrom(Expr\YieldFrom $node, int $precedence, int $lhsPrecedence): string
  21848. {
  21849. return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr, $precedence, $lhsPrecedence);
  21850. }
  21851. protected function pExpr_Print(Expr\Print_ $node, int $precedence, int $lhsPrecedence): string
  21852. {
  21853. return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr, $precedence, $lhsPrecedence);
  21854. }
  21855. // Casts
  21856. protected function pExpr_Cast_Int(Cast\Int_ $node, int $precedence, int $lhsPrecedence): string
  21857. {
  21858. return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr, $precedence, $lhsPrecedence);
  21859. }
  21860. protected function pExpr_Cast_Double(Cast\Double $node, int $precedence, int $lhsPrecedence): string
  21861. {
  21862. $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE);
  21863. if ($kind === Cast\Double::KIND_DOUBLE) {
  21864. $cast = '(double)';
  21865. } elseif ($kind === Cast\Double::KIND_FLOAT) {
  21866. $cast = '(float)';
  21867. } else {
  21868. assert($kind === Cast\Double::KIND_REAL);
  21869. $cast = '(real)';
  21870. }
  21871. return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr, $precedence, $lhsPrecedence);
  21872. }
  21873. protected function pExpr_Cast_String(Cast\String_ $node, int $precedence, int $lhsPrecedence): string
  21874. {
  21875. return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr, $precedence, $lhsPrecedence);
  21876. }
  21877. protected function pExpr_Cast_Array(Cast\Array_ $node, int $precedence, int $lhsPrecedence): string
  21878. {
  21879. return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr, $precedence, $lhsPrecedence);
  21880. }
  21881. protected function pExpr_Cast_Object(Cast\Object_ $node, int $precedence, int $lhsPrecedence): string
  21882. {
  21883. return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr, $precedence, $lhsPrecedence);
  21884. }
  21885. protected function pExpr_Cast_Bool(Cast\Bool_ $node, int $precedence, int $lhsPrecedence): string
  21886. {
  21887. return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr, $precedence, $lhsPrecedence);
  21888. }
  21889. protected function pExpr_Cast_Unset(Cast\Unset_ $node, int $precedence, int $lhsPrecedence): string
  21890. {
  21891. return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr, $precedence, $lhsPrecedence);
  21892. }
  21893. // Function calls and similar constructs
  21894. protected function pExpr_FuncCall(Expr\FuncCall $node): string
  21895. {
  21896. return $this->pCallLhs($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
  21897. }
  21898. protected function pExpr_MethodCall(Expr\MethodCall $node): string
  21899. {
  21900. return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
  21901. }
  21902. protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node): string
  21903. {
  21904. return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
  21905. }
  21906. protected function pExpr_StaticCall(Expr\StaticCall $node): string
  21907. {
  21908. return $this->pStaticDereferenceLhs($node->class) . '::' . ($node->name instanceof Expr ? $node->name instanceof Expr\Variable ? $this->p($node->name) : '{' . $this->p($node->name) . '}' : $node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
  21909. }
  21910. protected function pExpr_Empty(Expr\Empty_ $node): string
  21911. {
  21912. return 'empty(' . $this->p($node->expr) . ')';
  21913. }
  21914. protected function pExpr_Isset(Expr\Isset_ $node): string
  21915. {
  21916. return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
  21917. }
  21918. protected function pExpr_Eval(Expr\Eval_ $node): string
  21919. {
  21920. return 'eval(' . $this->p($node->expr) . ')';
  21921. }
  21922. protected function pExpr_Include(Expr\Include_ $node, int $precedence, int $lhsPrecedence): string
  21923. {
  21924. static $map = [Expr\Include_::TYPE_INCLUDE => 'include', Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', Expr\Include_::TYPE_REQUIRE => 'require', Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once'];
  21925. return $this->pPrefixOp(Expr\Include_::class, $map[$node->type] . ' ', $node->expr, $precedence, $lhsPrecedence);
  21926. }
  21927. protected function pExpr_List(Expr\List_ $node): string
  21928. {
  21929. $syntax = $node->getAttribute('kind', $this->phpVersion->supportsShortArrayDestructuring() ? Expr\List_::KIND_ARRAY : Expr\List_::KIND_LIST);
  21930. if ($syntax === Expr\List_::KIND_ARRAY) {
  21931. return '[' . $this->pMaybeMultiline($node->items, \true) . ']';
  21932. } else {
  21933. return 'list(' . $this->pMaybeMultiline($node->items, \true) . ')';
  21934. }
  21935. }
  21936. // Other
  21937. protected function pExpr_Error(Expr\Error $node): string
  21938. {
  21939. throw new \LogicException('Cannot pretty-print AST with Error nodes');
  21940. }
  21941. protected function pExpr_Variable(Expr\Variable $node): string
  21942. {
  21943. if ($node->name instanceof Expr) {
  21944. return '${' . $this->p($node->name) . '}';
  21945. } else {
  21946. return '$' . $node->name;
  21947. }
  21948. }
  21949. protected function pExpr_Array(Expr\Array_ $node): string
  21950. {
  21951. $syntax = $node->getAttribute('kind', $this->shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
  21952. if ($syntax === Expr\Array_::KIND_SHORT) {
  21953. return '[' . $this->pMaybeMultiline($node->items, \true) . ']';
  21954. } else {
  21955. return 'array(' . $this->pMaybeMultiline($node->items, \true) . ')';
  21956. }
  21957. }
  21958. protected function pKey(?Node $node): string
  21959. {
  21960. if ($node === null) {
  21961. return '';
  21962. }
  21963. // => is not really an operator and does not typically participate in precedence resolution.
  21964. // However, there is an exception if yield expressions with keys are involved:
  21965. // [yield $a => $b] is interpreted as [(yield $a => $b)], so we need to ensure that
  21966. // [(yield $a) => $b] is printed with parentheses. We approximate this by lowering the LHS
  21967. // precedence to that of yield (which will also print unnecessary parentheses for rare low
  21968. // precedence unary operators like include).
  21969. $yieldPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
  21970. return $this->p($node, self::MAX_PRECEDENCE, $yieldPrecedence) . ' => ';
  21971. }
  21972. protected function pArrayItem(Node\ArrayItem $node): string
  21973. {
  21974. return $this->pKey($node->key) . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
  21975. }
  21976. protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node): string
  21977. {
  21978. return $this->pDereferenceLhs($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
  21979. }
  21980. protected function pExpr_ConstFetch(Expr\ConstFetch $node): string
  21981. {
  21982. return $this->p($node->name);
  21983. }
  21984. protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string
  21985. {
  21986. return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name);
  21987. }
  21988. protected function pExpr_PropertyFetch(Expr\PropertyFetch $node): string
  21989. {
  21990. return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
  21991. }
  21992. protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node): string
  21993. {
  21994. return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name);
  21995. }
  21996. protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node): string
  21997. {
  21998. return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
  21999. }
  22000. protected function pExpr_ShellExec(Expr\ShellExec $node): string
  22001. {
  22002. return '`' . $this->pEncapsList($node->parts, '`') . '`';
  22003. }
  22004. protected function pExpr_Closure(Expr\Closure $node): string
  22005. {
  22006. return $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (!empty($node->uses) ? ' use (' . $this->pCommaSeparated($node->uses) . ')' : '') . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22007. }
  22008. protected function pExpr_Match(Expr\Match_ $node): string
  22009. {
  22010. return 'match (' . $this->p($node->cond) . ') {' . $this->pCommaSeparatedMultiline($node->arms, \true) . $this->nl . '}';
  22011. }
  22012. protected function pMatchArm(Node\MatchArm $node): string
  22013. {
  22014. $result = '';
  22015. if ($node->conds) {
  22016. for ($i = 0, $c = \count($node->conds); $i + 1 < $c; $i++) {
  22017. $result .= $this->p($node->conds[$i]) . ', ';
  22018. }
  22019. $result .= $this->pKey($node->conds[$i]);
  22020. } else {
  22021. $result = 'default => ';
  22022. }
  22023. return $result . $this->p($node->body);
  22024. }
  22025. protected function pExpr_ArrowFunction(Expr\ArrowFunction $node, int $precedence, int $lhsPrecedence): string
  22026. {
  22027. return $this->pPrefixOp(Expr\ArrowFunction::class, $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'fn' . ($node->byRef ? '&' : '') . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' => ', $node->expr, $precedence, $lhsPrecedence);
  22028. }
  22029. protected function pClosureUse(Node\ClosureUse $node): string
  22030. {
  22031. return ($node->byRef ? '&' : '') . $this->p($node->var);
  22032. }
  22033. protected function pExpr_New(Expr\New_ $node): string
  22034. {
  22035. if ($node->class instanceof Stmt\Class_) {
  22036. $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
  22037. return 'new ' . $this->pClassCommon($node->class, $args);
  22038. }
  22039. return 'new ' . $this->pNewOperand($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')';
  22040. }
  22041. protected function pExpr_Clone(Expr\Clone_ $node, int $precedence, int $lhsPrecedence): string
  22042. {
  22043. return $this->pPrefixOp(Expr\Clone_::class, 'clone ', $node->expr, $precedence, $lhsPrecedence);
  22044. }
  22045. protected function pExpr_Ternary(Expr\Ternary $node, int $precedence, int $lhsPrecedence): string
  22046. {
  22047. // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
  22048. // this is okay because the part between ? and : never needs parentheses.
  22049. return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else, $precedence, $lhsPrecedence);
  22050. }
  22051. protected function pExpr_Exit(Expr\Exit_ $node): string
  22052. {
  22053. $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
  22054. return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
  22055. }
  22056. protected function pExpr_Throw(Expr\Throw_ $node, int $precedence, int $lhsPrecedence): string
  22057. {
  22058. return $this->pPrefixOp(Expr\Throw_::class, 'throw ', $node->expr, $precedence, $lhsPrecedence);
  22059. }
  22060. protected function pExpr_Yield(Expr\Yield_ $node, int $precedence, int $lhsPrecedence): string
  22061. {
  22062. if ($node->value === null) {
  22063. $opPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
  22064. return $opPrecedence >= $lhsPrecedence ? '(yield)' : 'yield';
  22065. } else {
  22066. if (!$this->phpVersion->supportsYieldWithoutParentheses()) {
  22067. return '(yield ' . $this->pKey($node->key) . $this->p($node->value) . ')';
  22068. }
  22069. return $this->pPrefixOp(Expr\Yield_::class, 'yield ' . $this->pKey($node->key), $node->value, $precedence, $lhsPrecedence);
  22070. }
  22071. }
  22072. // Declarations
  22073. protected function pStmt_Namespace(Stmt\Namespace_ $node): string
  22074. {
  22075. if ($this->canUseSemicolonNamespaces) {
  22076. return 'namespace ' . $this->p($node->name) . ';' . $this->nl . $this->pStmts($node->stmts, \false);
  22077. } else {
  22078. return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22079. }
  22080. }
  22081. protected function pStmt_Use(Stmt\Use_ $node): string
  22082. {
  22083. return 'use ' . $this->pUseType($node->type) . $this->pCommaSeparated($node->uses) . ';';
  22084. }
  22085. protected function pStmt_GroupUse(Stmt\GroupUse $node): string
  22086. {
  22087. return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) . '\{' . $this->pCommaSeparated($node->uses) . '};';
  22088. }
  22089. protected function pUseItem(Node\UseItem $node): string
  22090. {
  22091. return $this->pUseType($node->type) . $this->p($node->name) . (null !== $node->alias ? ' as ' . $node->alias : '');
  22092. }
  22093. protected function pUseType(int $type): string
  22094. {
  22095. return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
  22096. }
  22097. protected function pStmt_Interface(Stmt\Interface_ $node): string
  22098. {
  22099. return $this->pAttrGroups($node->attrGroups) . 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22100. }
  22101. protected function pStmt_Enum(Stmt\Enum_ $node): string
  22102. {
  22103. return $this->pAttrGroups($node->attrGroups) . 'enum ' . $node->name . ($node->scalarType ? ' : ' . $this->p($node->scalarType) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22104. }
  22105. protected function pStmt_Class(Stmt\Class_ $node): string
  22106. {
  22107. return $this->pClassCommon($node, ' ' . $node->name);
  22108. }
  22109. protected function pStmt_Trait(Stmt\Trait_ $node): string
  22110. {
  22111. return $this->pAttrGroups($node->attrGroups) . 'trait ' . $node->name . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22112. }
  22113. protected function pStmt_EnumCase(Stmt\EnumCase $node): string
  22114. {
  22115. return $this->pAttrGroups($node->attrGroups) . 'case ' . $node->name . ($node->expr ? ' = ' . $this->p($node->expr) : '') . ';';
  22116. }
  22117. protected function pStmt_TraitUse(Stmt\TraitUse $node): string
  22118. {
  22119. return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}');
  22120. }
  22121. protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node): string
  22122. {
  22123. return $this->p($node->trait) . '::' . $node->method . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
  22124. }
  22125. protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node): string
  22126. {
  22127. return (null !== $node->trait ? $this->p($node->trait) . '::' : '') . $node->method . ' as' . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') . (null !== $node->newName ? ' ' . $node->newName : '') . ';';
  22128. }
  22129. protected function pStmt_Property(Stmt\Property $node): string
  22130. {
  22131. return $this->pAttrGroups($node->attrGroups) . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . ($node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->props) . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ';');
  22132. }
  22133. protected function pPropertyItem(Node\PropertyItem $node): string
  22134. {
  22135. return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
  22136. }
  22137. protected function pPropertyHook(Node\PropertyHook $node): string
  22138. {
  22139. return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . ($node->byRef ? '&' : '') . $node->name . ($node->params ? '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' : '') . (\is_array($node->body) ? ' {' . $this->pStmts($node->body) . $this->nl . '}' : ($node->body !== null ? ' => ' . $this->p($node->body) : '') . ';');
  22140. }
  22141. protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string
  22142. {
  22143. return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . (null !== $node->stmts ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
  22144. }
  22145. protected function pStmt_ClassConst(Stmt\ClassConst $node): string
  22146. {
  22147. return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'const ' . (null !== $node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->consts) . ';';
  22148. }
  22149. protected function pStmt_Function(Stmt\Function_ $node): string
  22150. {
  22151. return $this->pAttrGroups($node->attrGroups) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22152. }
  22153. protected function pStmt_Const(Stmt\Const_ $node): string
  22154. {
  22155. return 'const ' . $this->pCommaSeparated($node->consts) . ';';
  22156. }
  22157. protected function pStmt_Declare(Stmt\Declare_ $node): string
  22158. {
  22159. return 'declare (' . $this->pCommaSeparated($node->declares) . ')' . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
  22160. }
  22161. protected function pDeclareItem(Node\DeclareItem $node): string
  22162. {
  22163. return $node->key . '=' . $this->p($node->value);
  22164. }
  22165. // Control flow
  22166. protected function pStmt_If(Stmt\If_ $node): string
  22167. {
  22168. return 'if (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') . (null !== $node->else ? ' ' . $this->p($node->else) : '');
  22169. }
  22170. protected function pStmt_ElseIf(Stmt\ElseIf_ $node): string
  22171. {
  22172. return 'elseif (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22173. }
  22174. protected function pStmt_Else(Stmt\Else_ $node): string
  22175. {
  22176. if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) {
  22177. // Print as "else if" rather than "else { if }"
  22178. return 'else ' . $this->p($node->stmts[0]);
  22179. }
  22180. return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22181. }
  22182. protected function pStmt_For(Stmt\For_ $node): string
  22183. {
  22184. return 'for (' . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') . $this->pCommaSeparated($node->loop) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22185. }
  22186. protected function pStmt_Foreach(Stmt\Foreach_ $node): string
  22187. {
  22188. return 'foreach (' . $this->p($node->expr) . ' as ' . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22189. }
  22190. protected function pStmt_While(Stmt\While_ $node): string
  22191. {
  22192. return 'while (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22193. }
  22194. protected function pStmt_Do(Stmt\Do_ $node): string
  22195. {
  22196. return 'do {' . $this->pStmts($node->stmts) . $this->nl . '} while (' . $this->p($node->cond) . ');';
  22197. }
  22198. protected function pStmt_Switch(Stmt\Switch_ $node): string
  22199. {
  22200. return 'switch (' . $this->p($node->cond) . ') {' . $this->pStmts($node->cases) . $this->nl . '}';
  22201. }
  22202. protected function pStmt_Case(Stmt\Case_ $node): string
  22203. {
  22204. return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' . $this->pStmts($node->stmts);
  22205. }
  22206. protected function pStmt_TryCatch(Stmt\TryCatch $node): string
  22207. {
  22208. return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') . ($node->finally !== null ? ' ' . $this->p($node->finally) : '');
  22209. }
  22210. protected function pStmt_Catch(Stmt\Catch_ $node): string
  22211. {
  22212. return 'catch (' . $this->pImplode($node->types, '|') . ($node->var !== null ? ' ' . $this->p($node->var) : '') . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22213. }
  22214. protected function pStmt_Finally(Stmt\Finally_ $node): string
  22215. {
  22216. return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}';
  22217. }
  22218. protected function pStmt_Break(Stmt\Break_ $node): string
  22219. {
  22220. return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
  22221. }
  22222. protected function pStmt_Continue(Stmt\Continue_ $node): string
  22223. {
  22224. return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
  22225. }
  22226. protected function pStmt_Return(Stmt\Return_ $node): string
  22227. {
  22228. return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
  22229. }
  22230. protected function pStmt_Label(Stmt\Label $node): string
  22231. {
  22232. return $node->name . ':';
  22233. }
  22234. protected function pStmt_Goto(Stmt\Goto_ $node): string
  22235. {
  22236. return 'goto ' . $node->name . ';';
  22237. }
  22238. // Other
  22239. protected function pStmt_Expression(Stmt\Expression $node): string
  22240. {
  22241. return $this->p($node->expr) . ';';
  22242. }
  22243. protected function pStmt_Echo(Stmt\Echo_ $node): string
  22244. {
  22245. return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
  22246. }
  22247. protected function pStmt_Static(Stmt\Static_ $node): string
  22248. {
  22249. return 'static ' . $this->pCommaSeparated($node->vars) . ';';
  22250. }
  22251. protected function pStmt_Global(Stmt\Global_ $node): string
  22252. {
  22253. return 'global ' . $this->pCommaSeparated($node->vars) . ';';
  22254. }
  22255. protected function pStaticVar(Node\StaticVar $node): string
  22256. {
  22257. return $this->p($node->var) . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
  22258. }
  22259. protected function pStmt_Unset(Stmt\Unset_ $node): string
  22260. {
  22261. return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
  22262. }
  22263. protected function pStmt_InlineHTML(Stmt\InlineHTML $node): string
  22264. {
  22265. $newline = $node->getAttribute('hasLeadingNewline', \true) ? $this->newline : '';
  22266. return '?>' . $newline . $node->value . '<?php ';
  22267. }
  22268. protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node): string
  22269. {
  22270. return '__halt_compiler();' . $node->remaining;
  22271. }
  22272. protected function pStmt_Nop(Stmt\Nop $node): string
  22273. {
  22274. return '';
  22275. }
  22276. protected function pStmt_Block(Stmt\Block $node): string
  22277. {
  22278. return '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22279. }
  22280. // Helpers
  22281. protected function pClassCommon(Stmt\Class_ $node, string $afterClassToken): string
  22282. {
  22283. return $this->pAttrGroups($node->attrGroups, $node->name === null) . $this->pModifiers($node->flags) . 'class' . $afterClassToken . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
  22284. }
  22285. protected function pObjectProperty(Node $node): string
  22286. {
  22287. if ($node instanceof Expr) {
  22288. return '{' . $this->p($node) . '}';
  22289. } else {
  22290. assert($node instanceof Node\Identifier);
  22291. return $node->name;
  22292. }
  22293. }
  22294. /** @param (Expr|Node\InterpolatedStringPart)[] $encapsList */
  22295. protected function pEncapsList(array $encapsList, ?string $quote): string
  22296. {
  22297. $return = '';
  22298. foreach ($encapsList as $element) {
  22299. if ($element instanceof Node\InterpolatedStringPart) {
  22300. $return .= $this->escapeString($element->value, $quote);
  22301. } else {
  22302. $return .= '{' . $this->p($element) . '}';
  22303. }
  22304. }
  22305. return $return;
  22306. }
  22307. protected function pSingleQuotedString(string $string): string
  22308. {
  22309. // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or
  22310. // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to
  22311. // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even
  22312. // though that would be legal.
  22313. $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/';
  22314. return '\'' . preg_replace($regex, '\\\\$0', $string) . '\'';
  22315. }
  22316. protected function escapeString(string $string, ?string $quote): string
  22317. {
  22318. if (null === $quote) {
  22319. // For doc strings, don't escape newlines
  22320. $escaped = addcslashes($string, "\t\f\v\$\\");
  22321. // But do escape isolated \r. Combined with the terminating newline, it might get
  22322. // interpreted as \r\n and dropped from the string contents.
  22323. $escaped = preg_replace('/\r(?!\n)/', '\r', $escaped);
  22324. if ($this->phpVersion->supportsFlexibleHeredoc()) {
  22325. $escaped = $this->indentString($escaped);
  22326. }
  22327. } else {
  22328. $escaped = addcslashes($string, "\n\r\t\f\v\$" . $quote . "\\");
  22329. }
  22330. // Escape control characters and non-UTF-8 characters.
  22331. // Regex based on https://stackoverflow.com/a/11709412/385378.
  22332. $regex = '/(
  22333. [\x00-\x08\x0E-\x1F] # Control characters
  22334. | [\xC0-\xC1] # Invalid UTF-8 Bytes
  22335. | [\xF5-\xFF] # Invalid UTF-8 Bytes
  22336. | \xE0(?=[\x80-\x9F]) # Overlong encoding of prior code point
  22337. | \xF0(?=[\x80-\x8F]) # Overlong encoding of prior code point
  22338. | [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start
  22339. | [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start
  22340. | [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
  22341. | (?<=[\x00-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
  22342. | (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
  22343. | (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
  22344. | (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
  22345. | (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
  22346. )/x';
  22347. return preg_replace_callback($regex, function ($matches): string {
  22348. assert(strlen($matches[0]) === 1);
  22349. $hex = dechex(ord($matches[0]));
  22350. return '\x' . str_pad($hex, 2, '0', \STR_PAD_LEFT);
  22351. }, $escaped);
  22352. }
  22353. protected function containsEndLabel(string $string, string $label, bool $atStart = \true): bool
  22354. {
  22355. $start = $atStart ? '(?:^|[\r\n])[ \t]*' : '[\r\n][ \t]*';
  22356. return \false !== strpos($string, $label) && preg_match('/' . $start . $label . '(?:$|[^_A-Za-z0-9\x80-\xff])/', $string);
  22357. }
  22358. /** @param (Expr|Node\InterpolatedStringPart)[] $parts */
  22359. protected function encapsedContainsEndLabel(array $parts, string $label): bool
  22360. {
  22361. foreach ($parts as $i => $part) {
  22362. if ($part instanceof Node\InterpolatedStringPart && $this->containsEndLabel($this->escapeString($part->value, null), $label, $i === 0)) {
  22363. return \true;
  22364. }
  22365. }
  22366. return \false;
  22367. }
  22368. protected function pDereferenceLhs(Node $node): string
  22369. {
  22370. if (!$this->dereferenceLhsRequiresParens($node)) {
  22371. return $this->p($node);
  22372. } else {
  22373. return '(' . $this->p($node) . ')';
  22374. }
  22375. }
  22376. protected function pStaticDereferenceLhs(Node $node): string
  22377. {
  22378. if (!$this->staticDereferenceLhsRequiresParens($node)) {
  22379. return $this->p($node);
  22380. } else {
  22381. return '(' . $this->p($node) . ')';
  22382. }
  22383. }
  22384. protected function pCallLhs(Node $node): string
  22385. {
  22386. if (!$this->callLhsRequiresParens($node)) {
  22387. return $this->p($node);
  22388. } else {
  22389. return '(' . $this->p($node) . ')';
  22390. }
  22391. }
  22392. protected function pNewOperand(Node $node): string
  22393. {
  22394. if (!$this->newOperandRequiresParens($node)) {
  22395. return $this->p($node);
  22396. } else {
  22397. return '(' . $this->p($node) . ')';
  22398. }
  22399. }
  22400. /**
  22401. * @param Node[] $nodes
  22402. */
  22403. protected function hasNodeWithComments(array $nodes): bool
  22404. {
  22405. foreach ($nodes as $node) {
  22406. if ($node && $node->getComments()) {
  22407. return \true;
  22408. }
  22409. }
  22410. return \false;
  22411. }
  22412. /** @param Node[] $nodes */
  22413. protected function pMaybeMultiline(array $nodes, bool $trailingComma = \false): string
  22414. {
  22415. if (!$this->hasNodeWithComments($nodes)) {
  22416. return $this->pCommaSeparated($nodes);
  22417. } else {
  22418. return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
  22419. }
  22420. }
  22421. /** @param Node\AttributeGroup[] $nodes */
  22422. protected function pAttrGroups(array $nodes, bool $inline = \false): string
  22423. {
  22424. $result = '';
  22425. $sep = $inline ? ' ' : $this->nl;
  22426. foreach ($nodes as $node) {
  22427. $result .= $this->p($node) . $sep;
  22428. }
  22429. return $result;
  22430. }
  22431. }
  22432. <?php
  22433. declare (strict_types=1);
  22434. namespace PHPUnitPHAR\PhpParser;
  22435. use PHPUnitPHAR\PhpParser\Internal\DiffElem;
  22436. use PHPUnitPHAR\PhpParser\Internal\Differ;
  22437. use PHPUnitPHAR\PhpParser\Internal\PrintableNewAnonClassNode;
  22438. use PHPUnitPHAR\PhpParser\Internal\TokenStream;
  22439. use PHPUnitPHAR\PhpParser\Node\AttributeGroup;
  22440. use PHPUnitPHAR\PhpParser\Node\Expr;
  22441. use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
  22442. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
  22443. use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
  22444. use PHPUnitPHAR\PhpParser\Node\IntersectionType;
  22445. use PHPUnitPHAR\PhpParser\Node\MatchArm;
  22446. use PHPUnitPHAR\PhpParser\Node\Param;
  22447. use PHPUnitPHAR\PhpParser\Node\PropertyHook;
  22448. use PHPUnitPHAR\PhpParser\Node\Scalar;
  22449. use PHPUnitPHAR\PhpParser\Node\Stmt;
  22450. use PHPUnitPHAR\PhpParser\Node\UnionType;
  22451. abstract class PrettyPrinterAbstract implements PrettyPrinter
  22452. {
  22453. protected const FIXUP_PREC_LEFT = 0;
  22454. // LHS operand affected by precedence
  22455. protected const FIXUP_PREC_RIGHT = 1;
  22456. // RHS operand affected by precedence
  22457. protected const FIXUP_PREC_UNARY = 2;
  22458. // Only operand affected by precedence
  22459. protected const FIXUP_CALL_LHS = 3;
  22460. // LHS of call
  22461. protected const FIXUP_DEREF_LHS = 4;
  22462. // LHS of dereferencing operation
  22463. protected const FIXUP_STATIC_DEREF_LHS = 5;
  22464. // LHS of static dereferencing operation
  22465. protected const FIXUP_BRACED_NAME = 6;
  22466. // Name operand that may require bracing
  22467. protected const FIXUP_VAR_BRACED_NAME = 7;
  22468. // Name operand that may require ${} bracing
  22469. protected const FIXUP_ENCAPSED = 8;
  22470. // Encapsed string part
  22471. protected const FIXUP_NEW = 9;
  22472. // New/instanceof operand
  22473. protected const MAX_PRECEDENCE = 1000;
  22474. /** @var array<class-string, array{int, int, int}> */
  22475. protected array $precedenceMap = [
  22476. // [precedence, precedenceLHS, precedenceRHS]
  22477. // Where the latter two are the precedences to use for the LHS and RHS of a binary operator,
  22478. // where 1 is added to one of the sides depending on associativity. This information is not
  22479. // used for unary operators and set to -1.
  22480. Expr\Clone_::class => [-10, 0, 1],
  22481. BinaryOp\Pow::class => [0, 0, 1],
  22482. Expr\BitwiseNot::class => [10, -1, -1],
  22483. Expr\UnaryPlus::class => [10, -1, -1],
  22484. Expr\UnaryMinus::class => [10, -1, -1],
  22485. Cast\Int_::class => [10, -1, -1],
  22486. Cast\Double::class => [10, -1, -1],
  22487. Cast\String_::class => [10, -1, -1],
  22488. Cast\Array_::class => [10, -1, -1],
  22489. Cast\Object_::class => [10, -1, -1],
  22490. Cast\Bool_::class => [10, -1, -1],
  22491. Cast\Unset_::class => [10, -1, -1],
  22492. Expr\ErrorSuppress::class => [10, -1, -1],
  22493. Expr\Instanceof_::class => [20, -1, -1],
  22494. Expr\BooleanNot::class => [30, -1, -1],
  22495. BinaryOp\Mul::class => [40, 41, 40],
  22496. BinaryOp\Div::class => [40, 41, 40],
  22497. BinaryOp\Mod::class => [40, 41, 40],
  22498. BinaryOp\Plus::class => [50, 51, 50],
  22499. BinaryOp\Minus::class => [50, 51, 50],
  22500. BinaryOp\Concat::class => [50, 51, 50],
  22501. BinaryOp\ShiftLeft::class => [60, 61, 60],
  22502. BinaryOp\ShiftRight::class => [60, 61, 60],
  22503. BinaryOp\Smaller::class => [70, 70, 70],
  22504. BinaryOp\SmallerOrEqual::class => [70, 70, 70],
  22505. BinaryOp\Greater::class => [70, 70, 70],
  22506. BinaryOp\GreaterOrEqual::class => [70, 70, 70],
  22507. BinaryOp\Equal::class => [80, 80, 80],
  22508. BinaryOp\NotEqual::class => [80, 80, 80],
  22509. BinaryOp\Identical::class => [80, 80, 80],
  22510. BinaryOp\NotIdentical::class => [80, 80, 80],
  22511. BinaryOp\Spaceship::class => [80, 80, 80],
  22512. BinaryOp\BitwiseAnd::class => [90, 91, 90],
  22513. BinaryOp\BitwiseXor::class => [100, 101, 100],
  22514. BinaryOp\BitwiseOr::class => [110, 111, 110],
  22515. BinaryOp\BooleanAnd::class => [120, 121, 120],
  22516. BinaryOp\BooleanOr::class => [130, 131, 130],
  22517. BinaryOp\Coalesce::class => [140, 140, 141],
  22518. Expr\Ternary::class => [150, 150, 150],
  22519. Expr\Assign::class => [160, -1, -1],
  22520. Expr\AssignRef::class => [160, -1, -1],
  22521. AssignOp\Plus::class => [160, -1, -1],
  22522. AssignOp\Minus::class => [160, -1, -1],
  22523. AssignOp\Mul::class => [160, -1, -1],
  22524. AssignOp\Div::class => [160, -1, -1],
  22525. AssignOp\Concat::class => [160, -1, -1],
  22526. AssignOp\Mod::class => [160, -1, -1],
  22527. AssignOp\BitwiseAnd::class => [160, -1, -1],
  22528. AssignOp\BitwiseOr::class => [160, -1, -1],
  22529. AssignOp\BitwiseXor::class => [160, -1, -1],
  22530. AssignOp\ShiftLeft::class => [160, -1, -1],
  22531. AssignOp\ShiftRight::class => [160, -1, -1],
  22532. AssignOp\Pow::class => [160, -1, -1],
  22533. AssignOp\Coalesce::class => [160, -1, -1],
  22534. Expr\YieldFrom::class => [170, -1, -1],
  22535. Expr\Yield_::class => [175, -1, -1],
  22536. Expr\Print_::class => [180, -1, -1],
  22537. BinaryOp\LogicalAnd::class => [190, 191, 190],
  22538. BinaryOp\LogicalXor::class => [200, 201, 200],
  22539. BinaryOp\LogicalOr::class => [210, 211, 210],
  22540. Expr\Include_::class => [220, -1, -1],
  22541. Expr\ArrowFunction::class => [230, -1, -1],
  22542. Expr\Throw_::class => [240, -1, -1],
  22543. ];
  22544. /** @var int Current indentation level. */
  22545. protected int $indentLevel;
  22546. /** @var string String for single level of indentation */
  22547. private string $indent;
  22548. /** @var int Width in spaces to indent by. */
  22549. private int $indentWidth;
  22550. /** @var bool Whether to use tab indentation. */
  22551. private bool $useTabs;
  22552. /** @var int Width in spaces of one tab. */
  22553. private int $tabWidth = 4;
  22554. /** @var string Newline style. Does not include current indentation. */
  22555. protected string $newline;
  22556. /** @var string Newline including current indentation. */
  22557. protected string $nl;
  22558. /** @var string|null Token placed at end of doc string to ensure it is followed by a newline.
  22559. * Null if flexible doc strings are used. */
  22560. protected ?string $docStringEndToken;
  22561. /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */
  22562. protected bool $canUseSemicolonNamespaces;
  22563. /** @var bool Whether to use short array syntax if the node specifies no preference */
  22564. protected bool $shortArraySyntax;
  22565. /** @var PhpVersion PHP version to target */
  22566. protected PhpVersion $phpVersion;
  22567. /** @var TokenStream|null Original tokens for use in format-preserving pretty print */
  22568. protected ?TokenStream $origTokens;
  22569. /** @var Internal\Differ<Node> Differ for node lists */
  22570. protected Differ $nodeListDiffer;
  22571. /** @var array<string, bool> Map determining whether a certain character is a label character */
  22572. protected array $labelCharMap;
  22573. /**
  22574. * @var array<string, array<string, int>> Map from token classes and subnode names to FIXUP_* constants.
  22575. * This is used during format-preserving prints to place additional parens/braces if necessary.
  22576. */
  22577. protected array $fixupMap;
  22578. /**
  22579. * @var array<string, array{left?: int|string, right?: int|string}> Map from "{$node->getType()}->{$subNode}"
  22580. * to ['left' => $l, 'right' => $r], where $l and $r specify the token type that needs to be stripped
  22581. * when removing this node.
  22582. */
  22583. protected array $removalMap;
  22584. /**
  22585. * @var array<string, array{int|string|null, bool, string|null, string|null}> Map from
  22586. * "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight].
  22587. * $find is an optional token after which the insertion occurs. $extraLeft/Right
  22588. * are optionally added before/after the main insertions.
  22589. */
  22590. protected array $insertionMap;
  22591. /**
  22592. * @var array<string, string> Map From "{$class}->{$subNode}" to string that should be inserted
  22593. * between elements of this list subnode.
  22594. */
  22595. protected array $listInsertionMap;
  22596. /**
  22597. * @var array<string, array{int|string|null, string, string}>
  22598. */
  22599. protected array $emptyListInsertionMap;
  22600. /** @var array<string, array{string, int}> Map from "{$class}->{$subNode}" to [$printFn, $token]
  22601. * where $printFn is the function to print the modifiers and $token is the token before which
  22602. * the modifiers should be reprinted. */
  22603. protected array $modifierChangeMap;
  22604. /**
  22605. * Creates a pretty printer instance using the given options.
  22606. *
  22607. * Supported options:
  22608. * * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.4). This option
  22609. * controls compatibility of the generated code with older PHP
  22610. * versions in cases where a simple stylistic choice exists (e.g.
  22611. * array() vs []). It is safe to pretty-print an AST for a newer
  22612. * PHP version while specifying an older target (but the result will
  22613. * of course not be compatible with the older version in that case).
  22614. * * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
  22615. * * string $indent: The indentation to use. Should either be all spaces or a single
  22616. * tab. Defaults to four spaces (" ").
  22617. * * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
  22618. * syntax, if the node does not specify a format. Defaults to whether
  22619. * the phpVersion support short array syntax.
  22620. *
  22621. * @param array{
  22622. * phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool
  22623. * } $options Dictionary of formatting options
  22624. */
  22625. public function __construct(array $options = [])
  22626. {
  22627. $this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 4);
  22628. $this->newline = $options['newline'] ?? "\n";
  22629. if ($this->newline !== "\n" && $this->newline != "\r\n") {
  22630. throw new \LogicException('Option "newline" must be one of "\n" or "\r\n"');
  22631. }
  22632. $this->shortArraySyntax = $options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax();
  22633. $this->docStringEndToken = $this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . mt_rand();
  22634. $this->indent = $indent = $options['indent'] ?? ' ';
  22635. if ($indent === "\t") {
  22636. $this->useTabs = \true;
  22637. $this->indentWidth = $this->tabWidth;
  22638. } elseif ($indent === \str_repeat(' ', \strlen($indent))) {
  22639. $this->useTabs = \false;
  22640. $this->indentWidth = \strlen($indent);
  22641. } else {
  22642. throw new \LogicException('Option "indent" must either be all spaces or a single tab');
  22643. }
  22644. }
  22645. /**
  22646. * Reset pretty printing state.
  22647. */
  22648. protected function resetState(): void
  22649. {
  22650. $this->indentLevel = 0;
  22651. $this->nl = $this->newline;
  22652. $this->origTokens = null;
  22653. }
  22654. /**
  22655. * Set indentation level
  22656. *
  22657. * @param int $level Level in number of spaces
  22658. */
  22659. protected function setIndentLevel(int $level): void
  22660. {
  22661. $this->indentLevel = $level;
  22662. if ($this->useTabs) {
  22663. $tabs = \intdiv($level, $this->tabWidth);
  22664. $spaces = $level % $this->tabWidth;
  22665. $this->nl = $this->newline . \str_repeat("\t", $tabs) . \str_repeat(' ', $spaces);
  22666. } else {
  22667. $this->nl = $this->newline . \str_repeat(' ', $level);
  22668. }
  22669. }
  22670. /**
  22671. * Increase indentation level.
  22672. */
  22673. protected function indent(): void
  22674. {
  22675. $this->indentLevel += $this->indentWidth;
  22676. $this->nl .= $this->indent;
  22677. }
  22678. /**
  22679. * Decrease indentation level.
  22680. */
  22681. protected function outdent(): void
  22682. {
  22683. assert($this->indentLevel >= $this->indentWidth);
  22684. $this->setIndentLevel($this->indentLevel - $this->indentWidth);
  22685. }
  22686. /**
  22687. * Pretty prints an array of statements.
  22688. *
  22689. * @param Node[] $stmts Array of statements
  22690. *
  22691. * @return string Pretty printed statements
  22692. */
  22693. public function prettyPrint(array $stmts): string
  22694. {
  22695. $this->resetState();
  22696. $this->preprocessNodes($stmts);
  22697. return ltrim($this->handleMagicTokens($this->pStmts($stmts, \false)));
  22698. }
  22699. /**
  22700. * Pretty prints an expression.
  22701. *
  22702. * @param Expr $node Expression node
  22703. *
  22704. * @return string Pretty printed node
  22705. */
  22706. public function prettyPrintExpr(Expr $node): string
  22707. {
  22708. $this->resetState();
  22709. return $this->handleMagicTokens($this->p($node));
  22710. }
  22711. /**
  22712. * Pretty prints a file of statements (includes the opening <?php tag if it is required).
  22713. *
  22714. * @param Node[] $stmts Array of statements
  22715. *
  22716. * @return string Pretty printed statements
  22717. */
  22718. public function prettyPrintFile(array $stmts): string
  22719. {
  22720. if (!$stmts) {
  22721. return "<?php" . $this->newline . $this->newline;
  22722. }
  22723. $p = "<?php" . $this->newline . $this->newline . $this->prettyPrint($stmts);
  22724. if ($stmts[0] instanceof Stmt\InlineHTML) {
  22725. $p = preg_replace('/^<\?php\s+\?>\r?\n?/', '', $p);
  22726. }
  22727. if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) {
  22728. $p = preg_replace('/<\?php$/', '', rtrim($p));
  22729. }
  22730. return $p;
  22731. }
  22732. /**
  22733. * Preprocesses the top-level nodes to initialize pretty printer state.
  22734. *
  22735. * @param Node[] $nodes Array of nodes
  22736. */
  22737. protected function preprocessNodes(array $nodes): void
  22738. {
  22739. /* We can use semicolon-namespaces unless there is a global namespace declaration */
  22740. $this->canUseSemicolonNamespaces = \true;
  22741. foreach ($nodes as $node) {
  22742. if ($node instanceof Stmt\Namespace_ && null === $node->name) {
  22743. $this->canUseSemicolonNamespaces = \false;
  22744. break;
  22745. }
  22746. }
  22747. }
  22748. /**
  22749. * Handles (and removes) doc-string-end tokens.
  22750. */
  22751. protected function handleMagicTokens(string $str): string
  22752. {
  22753. if ($this->docStringEndToken !== null) {
  22754. // Replace doc-string-end tokens with nothing or a newline
  22755. $str = str_replace($this->docStringEndToken . ';' . $this->newline, ';' . $this->newline, $str);
  22756. $str = str_replace($this->docStringEndToken, $this->newline, $str);
  22757. }
  22758. return $str;
  22759. }
  22760. /**
  22761. * Pretty prints an array of nodes (statements) and indents them optionally.
  22762. *
  22763. * @param Node[] $nodes Array of nodes
  22764. * @param bool $indent Whether to indent the printed nodes
  22765. *
  22766. * @return string Pretty printed statements
  22767. */
  22768. protected function pStmts(array $nodes, bool $indent = \true): string
  22769. {
  22770. if ($indent) {
  22771. $this->indent();
  22772. }
  22773. $result = '';
  22774. foreach ($nodes as $node) {
  22775. $comments = $node->getComments();
  22776. if ($comments) {
  22777. $result .= $this->nl . $this->pComments($comments);
  22778. if ($node instanceof Stmt\Nop) {
  22779. continue;
  22780. }
  22781. }
  22782. $result .= $this->nl . $this->p($node);
  22783. }
  22784. if ($indent) {
  22785. $this->outdent();
  22786. }
  22787. return $result;
  22788. }
  22789. /**
  22790. * Pretty-print an infix operation while taking precedence into account.
  22791. *
  22792. * @param string $class Node class of operator
  22793. * @param Node $leftNode Left-hand side node
  22794. * @param string $operatorString String representation of the operator
  22795. * @param Node $rightNode Right-hand side node
  22796. * @param int $precedence Precedence of parent operator
  22797. * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
  22798. *
  22799. * @return string Pretty printed infix operation
  22800. */
  22801. protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode, int $precedence, int $lhsPrecedence): string
  22802. {
  22803. list($opPrecedence, $newPrecedenceLHS, $newPrecedenceRHS) = $this->precedenceMap[$class];
  22804. $prefix = '';
  22805. $suffix = '';
  22806. if ($opPrecedence >= $precedence) {
  22807. $prefix = '(';
  22808. $suffix = ')';
  22809. $lhsPrecedence = self::MAX_PRECEDENCE;
  22810. }
  22811. return $prefix . $this->p($leftNode, $newPrecedenceLHS, $newPrecedenceLHS) . $operatorString . $this->p($rightNode, $newPrecedenceRHS, $lhsPrecedence) . $suffix;
  22812. }
  22813. /**
  22814. * Pretty-print a prefix operation while taking precedence into account.
  22815. *
  22816. * @param string $class Node class of operator
  22817. * @param string $operatorString String representation of the operator
  22818. * @param Node $node Node
  22819. * @param int $precedence Precedence of parent operator
  22820. * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
  22821. *
  22822. * @return string Pretty printed prefix operation
  22823. */
  22824. protected function pPrefixOp(string $class, string $operatorString, Node $node, int $precedence, int $lhsPrecedence): string
  22825. {
  22826. $opPrecedence = $this->precedenceMap[$class][0];
  22827. $prefix = '';
  22828. $suffix = '';
  22829. if ($opPrecedence >= $lhsPrecedence) {
  22830. $prefix = '(';
  22831. $suffix = ')';
  22832. $lhsPrecedence = self::MAX_PRECEDENCE;
  22833. }
  22834. $printedArg = $this->p($node, $opPrecedence, $lhsPrecedence);
  22835. if ($operatorString === '+' && $printedArg[0] === '+' || $operatorString === '-' && $printedArg[0] === '-') {
  22836. // Avoid printing +(+$a) as ++$a and similar.
  22837. $printedArg = '(' . $printedArg . ')';
  22838. }
  22839. return $prefix . $operatorString . $printedArg . $suffix;
  22840. }
  22841. /**
  22842. * Pretty-print a postfix operation while taking precedence into account.
  22843. *
  22844. * @param string $class Node class of operator
  22845. * @param string $operatorString String representation of the operator
  22846. * @param Node $node Node
  22847. * @param int $precedence Precedence of parent operator
  22848. * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
  22849. *
  22850. * @return string Pretty printed postfix operation
  22851. */
  22852. protected function pPostfixOp(string $class, Node $node, string $operatorString, int $precedence, int $lhsPrecedence): string
  22853. {
  22854. $opPrecedence = $this->precedenceMap[$class][0];
  22855. $prefix = '';
  22856. $suffix = '';
  22857. if ($opPrecedence >= $precedence) {
  22858. $prefix = '(';
  22859. $suffix = ')';
  22860. $lhsPrecedence = self::MAX_PRECEDENCE;
  22861. }
  22862. if ($opPrecedence < $lhsPrecedence) {
  22863. $lhsPrecedence = $opPrecedence;
  22864. }
  22865. return $prefix . $this->p($node, $opPrecedence, $lhsPrecedence) . $operatorString . $suffix;
  22866. }
  22867. /**
  22868. * Pretty prints an array of nodes and implodes the printed values.
  22869. *
  22870. * @param Node[] $nodes Array of Nodes to be printed
  22871. * @param string $glue Character to implode with
  22872. *
  22873. * @return string Imploded pretty printed nodes> $pre
  22874. */
  22875. protected function pImplode(array $nodes, string $glue = ''): string
  22876. {
  22877. $pNodes = [];
  22878. foreach ($nodes as $node) {
  22879. if (null === $node) {
  22880. $pNodes[] = '';
  22881. } else {
  22882. $pNodes[] = $this->p($node);
  22883. }
  22884. }
  22885. return implode($glue, $pNodes);
  22886. }
  22887. /**
  22888. * Pretty prints an array of nodes and implodes the printed values with commas.
  22889. *
  22890. * @param Node[] $nodes Array of Nodes to be printed
  22891. *
  22892. * @return string Comma separated pretty printed nodes
  22893. */
  22894. protected function pCommaSeparated(array $nodes): string
  22895. {
  22896. return $this->pImplode($nodes, ', ');
  22897. }
  22898. /**
  22899. * Pretty prints a comma-separated list of nodes in multiline style, including comments.
  22900. *
  22901. * The result includes a leading newline and one level of indentation (same as pStmts).
  22902. *
  22903. * @param Node[] $nodes Array of Nodes to be printed
  22904. * @param bool $trailingComma Whether to use a trailing comma
  22905. *
  22906. * @return string Comma separated pretty printed nodes in multiline style
  22907. */
  22908. protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma): string
  22909. {
  22910. $this->indent();
  22911. $result = '';
  22912. $lastIdx = count($nodes) - 1;
  22913. foreach ($nodes as $idx => $node) {
  22914. if ($node !== null) {
  22915. $comments = $node->getComments();
  22916. if ($comments) {
  22917. $result .= $this->nl . $this->pComments($comments);
  22918. }
  22919. $result .= $this->nl . $this->p($node);
  22920. } else {
  22921. $result .= $this->nl;
  22922. }
  22923. if ($trailingComma || $idx !== $lastIdx) {
  22924. $result .= ',';
  22925. }
  22926. }
  22927. $this->outdent();
  22928. return $result;
  22929. }
  22930. /**
  22931. * Prints reformatted text of the passed comments.
  22932. *
  22933. * @param Comment[] $comments List of comments
  22934. *
  22935. * @return string Reformatted text of comments
  22936. */
  22937. protected function pComments(array $comments): string
  22938. {
  22939. $formattedComments = [];
  22940. foreach ($comments as $comment) {
  22941. $formattedComments[] = str_replace("\n", $this->nl, $comment->getReformattedText());
  22942. }
  22943. return implode($this->nl, $formattedComments);
  22944. }
  22945. /**
  22946. * Perform a format-preserving pretty print of an AST.
  22947. *
  22948. * The format preservation is best effort. For some changes to the AST the formatting will not
  22949. * be preserved (at least not locally).
  22950. *
  22951. * In order to use this method a number of prerequisites must be satisfied:
  22952. * * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
  22953. * * The CloningVisitor must be run on the AST prior to modification.
  22954. * * The original tokens must be provided, using the getTokens() method on the lexer.
  22955. *
  22956. * @param Node[] $stmts Modified AST with links to original AST
  22957. * @param Node[] $origStmts Original AST with token offset information
  22958. * @param Token[] $origTokens Tokens of the original code
  22959. */
  22960. public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string
  22961. {
  22962. $this->initializeNodeListDiffer();
  22963. $this->initializeLabelCharMap();
  22964. $this->initializeFixupMap();
  22965. $this->initializeRemovalMap();
  22966. $this->initializeInsertionMap();
  22967. $this->initializeListInsertionMap();
  22968. $this->initializeEmptyListInsertionMap();
  22969. $this->initializeModifierChangeMap();
  22970. $this->resetState();
  22971. $this->origTokens = new TokenStream($origTokens, $this->tabWidth);
  22972. $this->preprocessNodes($stmts);
  22973. $pos = 0;
  22974. $result = $this->pArray($stmts, $origStmts, $pos, 0, 'File', 'stmts', null);
  22975. if (null !== $result) {
  22976. $result .= $this->origTokens->getTokenCode($pos, count($origTokens) - 1, 0);
  22977. } else {
  22978. // Fallback
  22979. // TODO Add <?php properly
  22980. $result = "<?php" . $this->newline . $this->pStmts($stmts, \false);
  22981. }
  22982. return $this->handleMagicTokens($result);
  22983. }
  22984. protected function pFallback(Node $node, int $precedence, int $lhsPrecedence): string
  22985. {
  22986. return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence);
  22987. }
  22988. /**
  22989. * Pretty prints a node.
  22990. *
  22991. * This method also handles formatting preservation for nodes.
  22992. *
  22993. * @param Node $node Node to be pretty printed
  22994. * @param int $precedence Precedence of parent operator
  22995. * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
  22996. * @param bool $parentFormatPreserved Whether parent node has preserved formatting
  22997. *
  22998. * @return string Pretty printed node
  22999. */
  23000. protected function p(Node $node, int $precedence = self::MAX_PRECEDENCE, int $lhsPrecedence = self::MAX_PRECEDENCE, bool $parentFormatPreserved = \false): string
  23001. {
  23002. // No orig tokens means this is a normal pretty print without preservation of formatting
  23003. if (!$this->origTokens) {
  23004. return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence);
  23005. }
  23006. /** @var Node|null $origNode */
  23007. $origNode = $node->getAttribute('origNode');
  23008. if (null === $origNode) {
  23009. return $this->pFallback($node, $precedence, $lhsPrecedence);
  23010. }
  23011. $class = \get_class($node);
  23012. \assert($class === \get_class($origNode));
  23013. $startPos = $origNode->getStartTokenPos();
  23014. $endPos = $origNode->getEndTokenPos();
  23015. \assert($startPos >= 0 && $endPos >= 0);
  23016. $fallbackNode = $node;
  23017. if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) {
  23018. // Normalize node structure of anonymous classes
  23019. assert($origNode instanceof Expr\New_);
  23020. $node = PrintableNewAnonClassNode::fromNewNode($node);
  23021. $origNode = PrintableNewAnonClassNode::fromNewNode($origNode);
  23022. $class = PrintableNewAnonClassNode::class;
  23023. }
  23024. // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting
  23025. // is not preserved, then we need to use the fallback code to make sure the tags are
  23026. // printed.
  23027. if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) {
  23028. return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
  23029. }
  23030. $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos);
  23031. $type = $node->getType();
  23032. $fixupInfo = $this->fixupMap[$class] ?? null;
  23033. $result = '';
  23034. $pos = $startPos;
  23035. foreach ($node->getSubNodeNames() as $subNodeName) {
  23036. $subNode = $node->{$subNodeName};
  23037. $origSubNode = $origNode->{$subNodeName};
  23038. if (!$subNode instanceof Node && $subNode !== null || !$origSubNode instanceof Node && $origSubNode !== null) {
  23039. if ($subNode === $origSubNode) {
  23040. // Unchanged, can reuse old code
  23041. continue;
  23042. }
  23043. if (is_array($subNode) && is_array($origSubNode)) {
  23044. // Array subnode changed, we might be able to reconstruct it
  23045. $listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $class, $subNodeName, $fixupInfo[$subNodeName] ?? null);
  23046. if (null === $listResult) {
  23047. return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
  23048. }
  23049. $result .= $listResult;
  23050. continue;
  23051. }
  23052. // Check if this is a modifier change
  23053. $key = $class . '->' . $subNodeName;
  23054. if (!isset($this->modifierChangeMap[$key])) {
  23055. return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
  23056. }
  23057. [$printFn, $findToken] = $this->modifierChangeMap[$key];
  23058. $result .= $this->{$printFn}($subNode);
  23059. $pos = $this->origTokens->findRight($pos, $findToken);
  23060. continue;
  23061. }
  23062. $extraLeft = '';
  23063. $extraRight = '';
  23064. if ($origSubNode !== null) {
  23065. $subStartPos = $origSubNode->getStartTokenPos();
  23066. $subEndPos = $origSubNode->getEndTokenPos();
  23067. \assert($subStartPos >= 0 && $subEndPos >= 0);
  23068. } else {
  23069. if ($subNode === null) {
  23070. // Both null, nothing to do
  23071. continue;
  23072. }
  23073. // A node has been inserted, check if we have insertion information for it
  23074. $key = $type . '->' . $subNodeName;
  23075. if (!isset($this->insertionMap[$key])) {
  23076. return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
  23077. }
  23078. list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
  23079. if (null !== $findToken) {
  23080. $subStartPos = $this->origTokens->findRight($pos, $findToken) + (int) !$beforeToken;
  23081. } else {
  23082. $subStartPos = $pos;
  23083. }
  23084. if (null === $extraLeft && null !== $extraRight) {
  23085. // If inserting on the right only, skipping whitespace looks better
  23086. $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos);
  23087. }
  23088. $subEndPos = $subStartPos - 1;
  23089. }
  23090. if (null === $subNode) {
  23091. // A node has been removed, check if we have removal information for it
  23092. $key = $type . '->' . $subNodeName;
  23093. if (!isset($this->removalMap[$key])) {
  23094. return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
  23095. }
  23096. // Adjust positions to account for additional tokens that must be skipped
  23097. $removalInfo = $this->removalMap[$key];
  23098. if (isset($removalInfo['left'])) {
  23099. $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1;
  23100. }
  23101. if (isset($removalInfo['right'])) {
  23102. $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1;
  23103. }
  23104. }
  23105. $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment);
  23106. if (null !== $subNode) {
  23107. $result .= $extraLeft;
  23108. $origIndentLevel = $this->indentLevel;
  23109. $this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0));
  23110. // If it's the same node that was previously in this position, it certainly doesn't
  23111. // need fixup. It's important to check this here, because our fixup checks are more
  23112. // conservative than strictly necessary.
  23113. if (isset($fixupInfo[$subNodeName]) && $subNode->getAttribute('origNode') !== $origSubNode) {
  23114. $fixup = $fixupInfo[$subNodeName];
  23115. $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos);
  23116. } else {
  23117. $res = $this->p($subNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
  23118. }
  23119. $this->safeAppend($result, $res);
  23120. $this->setIndentLevel($origIndentLevel);
  23121. $result .= $extraRight;
  23122. }
  23123. $pos = $subEndPos + 1;
  23124. }
  23125. $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment);
  23126. return $result;
  23127. }
  23128. /**
  23129. * Perform a format-preserving pretty print of an array.
  23130. *
  23131. * @param Node[] $nodes New nodes
  23132. * @param Node[] $origNodes Original nodes
  23133. * @param int $pos Current token position (updated by reference)
  23134. * @param int $indentAdjustment Adjustment for indentation
  23135. * @param string $parentNodeClass Class of the containing node.
  23136. * @param string $subNodeName Name of array subnode.
  23137. * @param null|int $fixup Fixup information for array item nodes
  23138. *
  23139. * @return null|string Result of pretty print or null if cannot preserve formatting
  23140. */
  23141. protected function pArray(array $nodes, array $origNodes, int &$pos, int $indentAdjustment, string $parentNodeClass, string $subNodeName, ?int $fixup): ?string
  23142. {
  23143. $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes);
  23144. $mapKey = $parentNodeClass . '->' . $subNodeName;
  23145. $insertStr = $this->listInsertionMap[$mapKey] ?? null;
  23146. $isStmtList = $subNodeName === 'stmts';
  23147. $beforeFirstKeepOrReplace = \true;
  23148. $skipRemovedNode = \false;
  23149. $delayedAdd = [];
  23150. $lastElemIndentLevel = $this->indentLevel;
  23151. $insertNewline = \false;
  23152. if ($insertStr === "\n") {
  23153. $insertStr = '';
  23154. $insertNewline = \true;
  23155. }
  23156. if ($isStmtList && \count($origNodes) === 1 && \count($nodes) !== 1) {
  23157. $startPos = $origNodes[0]->getStartTokenPos();
  23158. $endPos = $origNodes[0]->getEndTokenPos();
  23159. \assert($startPos >= 0 && $endPos >= 0);
  23160. if (!$this->origTokens->haveBraces($startPos, $endPos)) {
  23161. // This was a single statement without braces, but either additional statements
  23162. // have been added, or the single statement has been removed. This requires the
  23163. // addition of braces. For now fall back.
  23164. // TODO: Try to preserve formatting
  23165. return null;
  23166. }
  23167. }
  23168. $result = '';
  23169. foreach ($diff as $i => $diffElem) {
  23170. $diffType = $diffElem->type;
  23171. /** @var Node|string|null $arrItem */
  23172. $arrItem = $diffElem->new;
  23173. /** @var Node|string|null $origArrItem */
  23174. $origArrItem = $diffElem->old;
  23175. if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) {
  23176. $beforeFirstKeepOrReplace = \false;
  23177. if ($origArrItem === null || $arrItem === null) {
  23178. // We can only handle the case where both are null
  23179. if ($origArrItem === $arrItem) {
  23180. continue;
  23181. }
  23182. return null;
  23183. }
  23184. if (!$arrItem instanceof Node || !$origArrItem instanceof Node) {
  23185. // We can only deal with nodes. This can occur for Names, which use string arrays.
  23186. return null;
  23187. }
  23188. $itemStartPos = $origArrItem->getStartTokenPos();
  23189. $itemEndPos = $origArrItem->getEndTokenPos();
  23190. \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos);
  23191. $origIndentLevel = $this->indentLevel;
  23192. $lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0);
  23193. $this->setIndentLevel($lastElemIndentLevel);
  23194. $comments = $arrItem->getComments();
  23195. $origComments = $origArrItem->getComments();
  23196. $commentStartPos = $origComments ? $origComments[0]->getStartTokenPos() : $itemStartPos;
  23197. \assert($commentStartPos >= 0);
  23198. if ($commentStartPos < $pos) {
  23199. // Comments may be assigned to multiple nodes if they start at the same position.
  23200. // Make sure we don't try to print them multiple times.
  23201. $commentStartPos = $itemStartPos;
  23202. }
  23203. if ($skipRemovedNode) {
  23204. if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) {
  23205. // We'd remove an opening/closing PHP tag.
  23206. // TODO: Preserve formatting.
  23207. $this->setIndentLevel($origIndentLevel);
  23208. return null;
  23209. }
  23210. } else {
  23211. $result .= $this->origTokens->getTokenCode($pos, $commentStartPos, $indentAdjustment);
  23212. }
  23213. if (!empty($delayedAdd)) {
  23214. /** @var Node $delayedAddNode */
  23215. foreach ($delayedAdd as $delayedAddNode) {
  23216. if ($insertNewline) {
  23217. $delayedAddComments = $delayedAddNode->getComments();
  23218. if ($delayedAddComments) {
  23219. $result .= $this->pComments($delayedAddComments) . $this->nl;
  23220. }
  23221. }
  23222. $this->safeAppend($result, $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true));
  23223. if ($insertNewline) {
  23224. $result .= $insertStr . $this->nl;
  23225. } else {
  23226. $result .= $insertStr;
  23227. }
  23228. }
  23229. $delayedAdd = [];
  23230. }
  23231. if ($comments !== $origComments) {
  23232. if ($comments) {
  23233. $result .= $this->pComments($comments) . $this->nl;
  23234. }
  23235. } else {
  23236. $result .= $this->origTokens->getTokenCode($commentStartPos, $itemStartPos, $indentAdjustment);
  23237. }
  23238. // If we had to remove anything, we have done so now.
  23239. $skipRemovedNode = \false;
  23240. } elseif ($diffType === DiffElem::TYPE_ADD) {
  23241. if (null === $insertStr) {
  23242. // We don't have insertion information for this list type
  23243. return null;
  23244. }
  23245. if (!$arrItem instanceof Node) {
  23246. // We only support list insertion of nodes.
  23247. return null;
  23248. }
  23249. // We go multiline if the original code was multiline,
  23250. // or if it's an array item with a comment above it.
  23251. // Match always uses multiline formatting.
  23252. if ($insertStr === ', ' && ($this->isMultiline($origNodes) || $arrItem->getComments() || $parentNodeClass === Expr\Match_::class)) {
  23253. $insertStr = ',';
  23254. $insertNewline = \true;
  23255. }
  23256. if ($beforeFirstKeepOrReplace) {
  23257. // Will be inserted at the next "replace" or "keep" element
  23258. $delayedAdd[] = $arrItem;
  23259. continue;
  23260. }
  23261. $itemStartPos = $pos;
  23262. $itemEndPos = $pos - 1;
  23263. $origIndentLevel = $this->indentLevel;
  23264. $this->setIndentLevel($lastElemIndentLevel);
  23265. if ($insertNewline) {
  23266. $result .= $insertStr . $this->nl;
  23267. $comments = $arrItem->getComments();
  23268. if ($comments) {
  23269. $result .= $this->pComments($comments) . $this->nl;
  23270. }
  23271. } else {
  23272. $result .= $insertStr;
  23273. }
  23274. } elseif ($diffType === DiffElem::TYPE_REMOVE) {
  23275. if (!$origArrItem instanceof Node) {
  23276. // We only support removal for nodes
  23277. return null;
  23278. }
  23279. $itemStartPos = $origArrItem->getStartTokenPos();
  23280. $itemEndPos = $origArrItem->getEndTokenPos();
  23281. \assert($itemStartPos >= 0 && $itemEndPos >= 0);
  23282. // Consider comments part of the node.
  23283. $origComments = $origArrItem->getComments();
  23284. if ($origComments) {
  23285. $itemStartPos = $origComments[0]->getStartTokenPos();
  23286. }
  23287. if ($i === 0) {
  23288. // If we're removing from the start, keep the tokens before the node and drop those after it,
  23289. // instead of the other way around.
  23290. $result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
  23291. $skipRemovedNode = \true;
  23292. } else if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) {
  23293. // We'd remove an opening/closing PHP tag.
  23294. // TODO: Preserve formatting.
  23295. return null;
  23296. }
  23297. $pos = $itemEndPos + 1;
  23298. continue;
  23299. } else {
  23300. throw new \Exception("Shouldn't happen");
  23301. }
  23302. if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) {
  23303. $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos);
  23304. } else {
  23305. $res = $this->p($arrItem, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
  23306. }
  23307. $this->safeAppend($result, $res);
  23308. $this->setIndentLevel($origIndentLevel);
  23309. $pos = $itemEndPos + 1;
  23310. }
  23311. if ($skipRemovedNode) {
  23312. // TODO: Support removing single node.
  23313. return null;
  23314. }
  23315. if (!empty($delayedAdd)) {
  23316. if (!isset($this->emptyListInsertionMap[$mapKey])) {
  23317. return null;
  23318. }
  23319. list($findToken, $extraLeft, $extraRight) = $this->emptyListInsertionMap[$mapKey];
  23320. if (null !== $findToken) {
  23321. $insertPos = $this->origTokens->findRight($pos, $findToken) + 1;
  23322. $result .= $this->origTokens->getTokenCode($pos, $insertPos, $indentAdjustment);
  23323. $pos = $insertPos;
  23324. }
  23325. $first = \true;
  23326. $result .= $extraLeft;
  23327. foreach ($delayedAdd as $delayedAddNode) {
  23328. if (!$first) {
  23329. $result .= $insertStr;
  23330. if ($insertNewline) {
  23331. $result .= $this->nl;
  23332. }
  23333. }
  23334. $result .= $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
  23335. $first = \false;
  23336. }
  23337. $result .= $extraRight === "\n" ? $this->nl : $extraRight;
  23338. }
  23339. return $result;
  23340. }
  23341. /**
  23342. * Print node with fixups.
  23343. *
  23344. * Fixups here refer to the addition of extra parentheses, braces or other characters, that
  23345. * are required to preserve program semantics in a certain context (e.g. to maintain precedence
  23346. * or because only certain expressions are allowed in certain places).
  23347. *
  23348. * @param int $fixup Fixup type
  23349. * @param Node $subNode Subnode to print
  23350. * @param string|null $parentClass Class of parent node
  23351. * @param int $subStartPos Original start pos of subnode
  23352. * @param int $subEndPos Original end pos of subnode
  23353. *
  23354. * @return string Result of fixed-up print of subnode
  23355. */
  23356. protected function pFixup(int $fixup, Node $subNode, ?string $parentClass, int $subStartPos, int $subEndPos): string
  23357. {
  23358. switch ($fixup) {
  23359. case self::FIXUP_PREC_LEFT:
  23360. // We use a conservative approximation where lhsPrecedence == precedence.
  23361. if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23362. $precedence = $this->precedenceMap[$parentClass][1];
  23363. return $this->p($subNode, $precedence, $precedence);
  23364. }
  23365. break;
  23366. case self::FIXUP_PREC_RIGHT:
  23367. if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23368. $precedence = $this->precedenceMap[$parentClass][2];
  23369. return $this->p($subNode, $precedence, $precedence);
  23370. }
  23371. break;
  23372. case self::FIXUP_PREC_UNARY:
  23373. if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23374. $precedence = $this->precedenceMap[$parentClass][0];
  23375. return $this->p($subNode, $precedence, $precedence);
  23376. }
  23377. break;
  23378. case self::FIXUP_CALL_LHS:
  23379. if ($this->callLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23380. return '(' . $this->p($subNode) . ')';
  23381. }
  23382. break;
  23383. case self::FIXUP_DEREF_LHS:
  23384. if ($this->dereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23385. return '(' . $this->p($subNode) . ')';
  23386. }
  23387. break;
  23388. case self::FIXUP_STATIC_DEREF_LHS:
  23389. if ($this->staticDereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23390. return '(' . $this->p($subNode) . ')';
  23391. }
  23392. break;
  23393. case self::FIXUP_NEW:
  23394. if ($this->newOperandRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
  23395. return '(' . $this->p($subNode) . ')';
  23396. }
  23397. break;
  23398. case self::FIXUP_BRACED_NAME:
  23399. case self::FIXUP_VAR_BRACED_NAME:
  23400. if ($subNode instanceof Expr && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
  23401. return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') . '{' . $this->p($subNode) . '}';
  23402. }
  23403. break;
  23404. case self::FIXUP_ENCAPSED:
  23405. if (!$subNode instanceof Node\InterpolatedStringPart && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
  23406. return '{' . $this->p($subNode) . '}';
  23407. }
  23408. break;
  23409. default:
  23410. throw new \Exception('Cannot happen');
  23411. }
  23412. // Nothing special to do
  23413. return $this->p($subNode);
  23414. }
  23415. /**
  23416. * Appends to a string, ensuring whitespace between label characters.
  23417. *
  23418. * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x".
  23419. * Without safeAppend the result would be "echox", which does not preserve semantics.
  23420. */
  23421. protected function safeAppend(string &$str, string $append): void
  23422. {
  23423. if ($str === "") {
  23424. $str = $append;
  23425. return;
  23426. }
  23427. if ($append === "") {
  23428. return;
  23429. }
  23430. if (!$this->labelCharMap[$append[0]] || !$this->labelCharMap[$str[\strlen($str) - 1]]) {
  23431. $str .= $append;
  23432. } else {
  23433. $str .= " " . $append;
  23434. }
  23435. }
  23436. /**
  23437. * Determines whether the LHS of a call must be wrapped in parenthesis.
  23438. *
  23439. * @param Node $node LHS of a call
  23440. *
  23441. * @return bool Whether parentheses are required
  23442. */
  23443. protected function callLhsRequiresParens(Node $node): bool
  23444. {
  23445. return !($node instanceof Node\Name || $node instanceof Expr\Variable || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_);
  23446. }
  23447. /**
  23448. * Determines whether the LHS of an array/object operation must be wrapped in parentheses.
  23449. *
  23450. * @param Node $node LHS of dereferencing operation
  23451. *
  23452. * @return bool Whether parentheses are required
  23453. */
  23454. protected function dereferenceLhsRequiresParens(Node $node): bool
  23455. {
  23456. // A constant can occur on the LHS of an array/object deref, but not a static deref.
  23457. return $this->staticDereferenceLhsRequiresParens($node) && !$node instanceof Expr\ConstFetch;
  23458. }
  23459. /**
  23460. * Determines whether the LHS of a static operation must be wrapped in parentheses.
  23461. *
  23462. * @param Node $node LHS of dereferencing operation
  23463. *
  23464. * @return bool Whether parentheses are required
  23465. */
  23466. protected function staticDereferenceLhsRequiresParens(Node $node): bool
  23467. {
  23468. return !($node instanceof Expr\Variable || $node instanceof Node\Name || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ || $node instanceof Scalar\String_ || $node instanceof Expr\ClassConstFetch);
  23469. }
  23470. /**
  23471. * Determines whether an expression used in "new" or "instanceof" requires parentheses.
  23472. *
  23473. * @param Node $node New or instanceof operand
  23474. *
  23475. * @return bool Whether parentheses are required
  23476. */
  23477. protected function newOperandRequiresParens(Node $node): bool
  23478. {
  23479. if ($node instanceof Node\Name || $node instanceof Expr\Variable) {
  23480. return \false;
  23481. }
  23482. if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch) {
  23483. return $this->newOperandRequiresParens($node->var);
  23484. }
  23485. if ($node instanceof Expr\StaticPropertyFetch) {
  23486. return $this->newOperandRequiresParens($node->class);
  23487. }
  23488. return \true;
  23489. }
  23490. /**
  23491. * Print modifiers, including trailing whitespace.
  23492. *
  23493. * @param int $modifiers Modifier mask to print
  23494. *
  23495. * @return string Printed modifiers
  23496. */
  23497. protected function pModifiers(int $modifiers): string
  23498. {
  23499. return ($modifiers & Modifiers::FINAL ? 'final ' : '') . ($modifiers & Modifiers::ABSTRACT ? 'abstract ' : '') . ($modifiers & Modifiers::PUBLIC ? 'public ' : '') . ($modifiers & Modifiers::PROTECTED ? 'protected ' : '') . ($modifiers & Modifiers::PRIVATE ? 'private ' : '') . ($modifiers & Modifiers::PUBLIC_SET ? 'public(set) ' : '') . ($modifiers & Modifiers::PROTECTED_SET ? 'protected(set) ' : '') . ($modifiers & Modifiers::PRIVATE_SET ? 'private(set) ' : '') . ($modifiers & Modifiers::STATIC ? 'static ' : '') . ($modifiers & Modifiers::READONLY ? 'readonly ' : '');
  23500. }
  23501. protected function pStatic(bool $static): string
  23502. {
  23503. return $static ? 'static ' : '';
  23504. }
  23505. /**
  23506. * Determine whether a list of nodes uses multiline formatting.
  23507. *
  23508. * @param (Node|null)[] $nodes Node list
  23509. *
  23510. * @return bool Whether multiline formatting is used
  23511. */
  23512. protected function isMultiline(array $nodes): bool
  23513. {
  23514. if (\count($nodes) < 2) {
  23515. return \false;
  23516. }
  23517. $pos = -1;
  23518. foreach ($nodes as $node) {
  23519. if (null === $node) {
  23520. continue;
  23521. }
  23522. $endPos = $node->getEndTokenPos() + 1;
  23523. if ($pos >= 0) {
  23524. $text = $this->origTokens->getTokenCode($pos, $endPos, 0);
  23525. if (\false === strpos($text, "\n")) {
  23526. // We require that a newline is present between *every* item. If the formatting
  23527. // is inconsistent, with only some items having newlines, we don't consider it
  23528. // as multiline
  23529. return \false;
  23530. }
  23531. }
  23532. $pos = $endPos;
  23533. }
  23534. return \true;
  23535. }
  23536. /**
  23537. * Lazily initializes label char map.
  23538. *
  23539. * The label char map determines whether a certain character may occur in a label.
  23540. */
  23541. protected function initializeLabelCharMap(): void
  23542. {
  23543. if (isset($this->labelCharMap)) {
  23544. return;
  23545. }
  23546. $this->labelCharMap = [];
  23547. for ($i = 0; $i < 256; $i++) {
  23548. $chr = chr($i);
  23549. $this->labelCharMap[$chr] = $i >= 0x80 || ctype_alnum($chr);
  23550. }
  23551. if ($this->phpVersion->allowsDelInIdentifiers()) {
  23552. $this->labelCharMap[""] = \true;
  23553. }
  23554. }
  23555. /**
  23556. * Lazily initializes node list differ.
  23557. *
  23558. * The node list differ is used to determine differences between two array subnodes.
  23559. */
  23560. protected function initializeNodeListDiffer(): void
  23561. {
  23562. if (isset($this->nodeListDiffer)) {
  23563. return;
  23564. }
  23565. $this->nodeListDiffer = new Internal\Differ(function ($a, $b) {
  23566. if ($a instanceof Node && $b instanceof Node) {
  23567. return $a === $b->getAttribute('origNode');
  23568. }
  23569. // Can happen for array destructuring
  23570. return $a === null && $b === null;
  23571. });
  23572. }
  23573. /**
  23574. * Lazily initializes fixup map.
  23575. *
  23576. * The fixup map is used to determine whether a certain subnode of a certain node may require
  23577. * some kind of "fixup" operation, e.g. the addition of parenthesis or braces.
  23578. */
  23579. protected function initializeFixupMap(): void
  23580. {
  23581. if (isset($this->fixupMap)) {
  23582. return;
  23583. }
  23584. $this->fixupMap = [Expr\Instanceof_::class => ['expr' => self::FIXUP_PREC_UNARY, 'class' => self::FIXUP_NEW], Expr\Ternary::class => ['cond' => self::FIXUP_PREC_LEFT, 'else' => self::FIXUP_PREC_RIGHT], Expr\Yield_::class => ['value' => self::FIXUP_PREC_UNARY], Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], Expr\StaticCall::class => ['class' => self::FIXUP_STATIC_DEREF_LHS], Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], Expr\ClassConstFetch::class => ['class' => self::FIXUP_STATIC_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\New_::class => ['class' => self::FIXUP_NEW], Expr\MethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\NullsafeMethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\StaticPropertyFetch::class => ['class' => self::FIXUP_STATIC_DEREF_LHS, 'name' => self::FIXUP_VAR_BRACED_NAME], Expr\PropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\NullsafePropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Scalar\InterpolatedString::class => ['parts' => self::FIXUP_ENCAPSED]];
  23585. $binaryOps = [BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class];
  23586. foreach ($binaryOps as $binaryOp) {
  23587. $this->fixupMap[$binaryOp] = ['left' => self::FIXUP_PREC_LEFT, 'right' => self::FIXUP_PREC_RIGHT];
  23588. }
  23589. $prefixOps = [Expr\Clone_::class, Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class, Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class, Expr\ArrowFunction::class, Expr\Throw_::class];
  23590. foreach ($prefixOps as $prefixOp) {
  23591. $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_UNARY];
  23592. }
  23593. }
  23594. /**
  23595. * Lazily initializes the removal map.
  23596. *
  23597. * The removal map is used to determine which additional tokens should be removed when a
  23598. * certain node is replaced by null.
  23599. */
  23600. protected function initializeRemovalMap(): void
  23601. {
  23602. if (isset($this->removalMap)) {
  23603. return;
  23604. }
  23605. $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE];
  23606. $stripLeft = ['left' => \T_WHITESPACE];
  23607. $stripRight = ['right' => \T_WHITESPACE];
  23608. $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW];
  23609. $stripColon = ['left' => ':'];
  23610. $stripEquals = ['left' => '='];
  23611. $this->removalMap = ['Expr_ArrayDimFetch->dim' => $stripBoth, 'ArrayItem->key' => $stripDoubleArrow, 'Expr_ArrowFunction->returnType' => $stripColon, 'Expr_Closure->returnType' => $stripColon, 'Expr_Exit->expr' => $stripBoth, 'Expr_Ternary->if' => $stripBoth, 'Expr_Yield->key' => $stripDoubleArrow, 'Expr_Yield->value' => $stripBoth, 'Param->type' => $stripRight, 'Param->default' => $stripEquals, 'Stmt_Break->num' => $stripBoth, 'Stmt_Catch->var' => $stripLeft, 'Stmt_ClassConst->type' => $stripRight, 'Stmt_ClassMethod->returnType' => $stripColon, 'Stmt_Class->extends' => ['left' => \T_EXTENDS], 'Stmt_Enum->scalarType' => $stripColon, 'Stmt_EnumCase->expr' => $stripEquals, 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], 'Stmt_Continue->num' => $stripBoth, 'Stmt_Foreach->keyVar' => $stripDoubleArrow, 'Stmt_Function->returnType' => $stripColon, 'Stmt_If->else' => $stripLeft, 'Stmt_Namespace->name' => $stripLeft, 'Stmt_Property->type' => $stripRight, 'PropertyItem->default' => $stripEquals, 'Stmt_Return->expr' => $stripBoth, 'Stmt_StaticVar->default' => $stripEquals, 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, 'Stmt_TryCatch->finally' => $stripLeft];
  23612. }
  23613. protected function initializeInsertionMap(): void
  23614. {
  23615. if (isset($this->insertionMap)) {
  23616. return;
  23617. }
  23618. // TODO: "yield" where both key and value are inserted doesn't work
  23619. // [$find, $beforeToken, $extraLeft, $extraRight]
  23620. $this->insertionMap = [
  23621. 'Expr_ArrayDimFetch->dim' => ['[', \false, null, null],
  23622. 'ArrayItem->key' => [null, \false, null, ' => '],
  23623. 'Expr_ArrowFunction->returnType' => [')', \false, ': ', null],
  23624. 'Expr_Closure->returnType' => [')', \false, ': ', null],
  23625. 'Expr_Ternary->if' => ['?', \false, ' ', ' '],
  23626. 'Expr_Yield->key' => [\T_YIELD, \false, null, ' => '],
  23627. 'Expr_Yield->value' => [\T_YIELD, \false, ' ', null],
  23628. 'Param->type' => [null, \false, null, ' '],
  23629. 'Param->default' => [null, \false, ' = ', null],
  23630. 'Stmt_Break->num' => [\T_BREAK, \false, ' ', null],
  23631. 'Stmt_Catch->var' => [null, \false, ' ', null],
  23632. 'Stmt_ClassMethod->returnType' => [')', \false, ': ', null],
  23633. 'Stmt_ClassConst->type' => [\T_CONST, \false, ' ', null],
  23634. 'Stmt_Class->extends' => [null, \false, ' extends ', null],
  23635. 'Stmt_Enum->scalarType' => [null, \false, ' : ', null],
  23636. 'Stmt_EnumCase->expr' => [null, \false, ' = ', null],
  23637. 'Expr_PrintableNewAnonClass->extends' => [null, \false, ' extends ', null],
  23638. 'Stmt_Continue->num' => [\T_CONTINUE, \false, ' ', null],
  23639. 'Stmt_Foreach->keyVar' => [\T_AS, \false, null, ' => '],
  23640. 'Stmt_Function->returnType' => [')', \false, ': ', null],
  23641. 'Stmt_If->else' => [null, \false, ' ', null],
  23642. 'Stmt_Namespace->name' => [\T_NAMESPACE, \false, ' ', null],
  23643. 'Stmt_Property->type' => [\T_VARIABLE, \true, null, ' '],
  23644. 'PropertyItem->default' => [null, \false, ' = ', null],
  23645. 'Stmt_Return->expr' => [\T_RETURN, \false, ' ', null],
  23646. 'Stmt_StaticVar->default' => [null, \false, ' = ', null],
  23647. //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO
  23648. 'Stmt_TryCatch->finally' => [null, \false, ' ', null],
  23649. ];
  23650. }
  23651. protected function initializeListInsertionMap(): void
  23652. {
  23653. if (isset($this->listInsertionMap)) {
  23654. return;
  23655. }
  23656. $this->listInsertionMap = [
  23657. // special
  23658. //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully
  23659. //'Scalar_InterpolatedString->parts' => '',
  23660. Stmt\Catch_::class . '->types' => '|',
  23661. UnionType::class . '->types' => '|',
  23662. IntersectionType::class . '->types' => '&',
  23663. Stmt\If_::class . '->elseifs' => ' ',
  23664. Stmt\TryCatch::class . '->catches' => ' ',
  23665. // comma-separated lists
  23666. Expr\Array_::class . '->items' => ', ',
  23667. Expr\ArrowFunction::class . '->params' => ', ',
  23668. Expr\Closure::class . '->params' => ', ',
  23669. Expr\Closure::class . '->uses' => ', ',
  23670. Expr\FuncCall::class . '->args' => ', ',
  23671. Expr\Isset_::class . '->vars' => ', ',
  23672. Expr\List_::class . '->items' => ', ',
  23673. Expr\MethodCall::class . '->args' => ', ',
  23674. Expr\NullsafeMethodCall::class . '->args' => ', ',
  23675. Expr\New_::class . '->args' => ', ',
  23676. PrintableNewAnonClassNode::class . '->args' => ', ',
  23677. Expr\StaticCall::class . '->args' => ', ',
  23678. Stmt\ClassConst::class . '->consts' => ', ',
  23679. Stmt\ClassMethod::class . '->params' => ', ',
  23680. Stmt\Class_::class . '->implements' => ', ',
  23681. Stmt\Enum_::class . '->implements' => ', ',
  23682. PrintableNewAnonClassNode::class . '->implements' => ', ',
  23683. Stmt\Const_::class . '->consts' => ', ',
  23684. Stmt\Declare_::class . '->declares' => ', ',
  23685. Stmt\Echo_::class . '->exprs' => ', ',
  23686. Stmt\For_::class . '->init' => ', ',
  23687. Stmt\For_::class . '->cond' => ', ',
  23688. Stmt\For_::class . '->loop' => ', ',
  23689. Stmt\Function_::class . '->params' => ', ',
  23690. Stmt\Global_::class . '->vars' => ', ',
  23691. Stmt\GroupUse::class . '->uses' => ', ',
  23692. Stmt\Interface_::class . '->extends' => ', ',
  23693. Expr\Match_::class . '->arms' => ', ',
  23694. Stmt\Property::class . '->props' => ', ',
  23695. Stmt\StaticVar::class . '->vars' => ', ',
  23696. Stmt\TraitUse::class . '->traits' => ', ',
  23697. Stmt\TraitUseAdaptation\Precedence::class . '->insteadof' => ', ',
  23698. Stmt\Unset_::class . '->vars' => ', ',
  23699. Stmt\UseUse::class . '->uses' => ', ',
  23700. MatchArm::class . '->conds' => ', ',
  23701. AttributeGroup::class . '->attrs' => ', ',
  23702. PropertyHook::class . '->params' => ', ',
  23703. // statement lists
  23704. Expr\Closure::class . '->stmts' => "\n",
  23705. Stmt\Case_::class . '->stmts' => "\n",
  23706. Stmt\Catch_::class . '->stmts' => "\n",
  23707. Stmt\Class_::class . '->stmts' => "\n",
  23708. Stmt\Enum_::class . '->stmts' => "\n",
  23709. PrintableNewAnonClassNode::class . '->stmts' => "\n",
  23710. Stmt\Interface_::class . '->stmts' => "\n",
  23711. Stmt\Trait_::class . '->stmts' => "\n",
  23712. Stmt\ClassMethod::class . '->stmts' => "\n",
  23713. Stmt\Declare_::class . '->stmts' => "\n",
  23714. Stmt\Do_::class . '->stmts' => "\n",
  23715. Stmt\ElseIf_::class . '->stmts' => "\n",
  23716. Stmt\Else_::class . '->stmts' => "\n",
  23717. Stmt\Finally_::class . '->stmts' => "\n",
  23718. Stmt\Foreach_::class . '->stmts' => "\n",
  23719. Stmt\For_::class . '->stmts' => "\n",
  23720. Stmt\Function_::class . '->stmts' => "\n",
  23721. Stmt\If_::class . '->stmts' => "\n",
  23722. Stmt\Namespace_::class . '->stmts' => "\n",
  23723. Stmt\Block::class . '->stmts' => "\n",
  23724. // Attribute groups
  23725. Stmt\Class_::class . '->attrGroups' => "\n",
  23726. Stmt\Enum_::class . '->attrGroups' => "\n",
  23727. Stmt\EnumCase::class . '->attrGroups' => "\n",
  23728. Stmt\Interface_::class . '->attrGroups' => "\n",
  23729. Stmt\Trait_::class . '->attrGroups' => "\n",
  23730. Stmt\Function_::class . '->attrGroups' => "\n",
  23731. Stmt\ClassMethod::class . '->attrGroups' => "\n",
  23732. Stmt\ClassConst::class . '->attrGroups' => "\n",
  23733. Stmt\Property::class . '->attrGroups' => "\n",
  23734. PrintableNewAnonClassNode::class . '->attrGroups' => ' ',
  23735. Expr\Closure::class . '->attrGroups' => ' ',
  23736. Expr\ArrowFunction::class . '->attrGroups' => ' ',
  23737. Param::class . '->attrGroups' => ' ',
  23738. PropertyHook::class . '->attrGroups' => ' ',
  23739. Stmt\Switch_::class . '->cases' => "\n",
  23740. Stmt\TraitUse::class . '->adaptations' => "\n",
  23741. Stmt\TryCatch::class . '->stmts' => "\n",
  23742. Stmt\While_::class . '->stmts' => "\n",
  23743. PropertyHook::class . '->body' => "\n",
  23744. Stmt\Property::class . '->hooks' => "\n",
  23745. Param::class . '->hooks' => "\n",
  23746. // dummy for top-level context
  23747. 'File->stmts' => "\n",
  23748. ];
  23749. }
  23750. protected function initializeEmptyListInsertionMap(): void
  23751. {
  23752. if (isset($this->emptyListInsertionMap)) {
  23753. return;
  23754. }
  23755. // TODO Insertion into empty statement lists.
  23756. // [$find, $extraLeft, $extraRight]
  23757. $this->emptyListInsertionMap = [Expr\ArrowFunction::class . '->params' => ['(', '', ''], Expr\Closure::class . '->uses' => [')', ' use (', ')'], Expr\Closure::class . '->params' => ['(', '', ''], Expr\FuncCall::class . '->args' => ['(', '', ''], Expr\MethodCall::class . '->args' => ['(', '', ''], Expr\NullsafeMethodCall::class . '->args' => ['(', '', ''], Expr\New_::class . '->args' => ['(', '', ''], PrintableNewAnonClassNode::class . '->args' => ['(', '', ''], PrintableNewAnonClassNode::class . '->implements' => [null, ' implements ', ''], Expr\StaticCall::class . '->args' => ['(', '', ''], Stmt\Class_::class . '->implements' => [null, ' implements ', ''], Stmt\Enum_::class . '->implements' => [null, ' implements ', ''], Stmt\ClassMethod::class . '->params' => ['(', '', ''], Stmt\Interface_::class . '->extends' => [null, ' extends ', ''], Stmt\Function_::class . '->params' => ['(', '', ''], Stmt\Interface_::class . '->attrGroups' => [null, '', "\n"], Stmt\Class_::class . '->attrGroups' => [null, '', "\n"], Stmt\ClassConst::class . '->attrGroups' => [null, '', "\n"], Stmt\ClassMethod::class . '->attrGroups' => [null, '', "\n"], Stmt\Function_::class . '->attrGroups' => [null, '', "\n"], Stmt\Property::class . '->attrGroups' => [null, '', "\n"], Stmt\Trait_::class . '->attrGroups' => [null, '', "\n"], Expr\ArrowFunction::class . '->attrGroups' => [null, '', ' '], Expr\Closure::class . '->attrGroups' => [null, '', ' '], PrintableNewAnonClassNode::class . '->attrGroups' => [\T_NEW, ' ', '']];
  23758. }
  23759. protected function initializeModifierChangeMap(): void
  23760. {
  23761. if (isset($this->modifierChangeMap)) {
  23762. return;
  23763. }
  23764. $this->modifierChangeMap = [Stmt\ClassConst::class . '->flags' => ['pModifiers', \T_CONST], Stmt\ClassMethod::class . '->flags' => ['pModifiers', \T_FUNCTION], Stmt\Class_::class . '->flags' => ['pModifiers', \T_CLASS], Stmt\Property::class . '->flags' => ['pModifiers', \T_VARIABLE], PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_CLASS], Param::class . '->flags' => ['pModifiers', \T_VARIABLE], PropertyHook::class . '->flags' => ['pModifiers', \T_STRING], Expr\Closure::class . '->static' => ['pStatic', \T_FUNCTION], Expr\ArrowFunction::class . '->static' => ['pStatic', \T_FN]];
  23765. // List of integer subnodes that are not modifiers:
  23766. // Expr_Include->type
  23767. // Stmt_GroupUse->type
  23768. // Stmt_Use->type
  23769. // UseItem->type
  23770. }
  23771. }
  23772. <?php
  23773. declare (strict_types=1);
  23774. namespace PHPUnitPHAR\PhpParser;
  23775. /**
  23776. * A PHP token. On PHP 8.0 this extends from PhpToken.
  23777. */
  23778. class Token extends Internal\TokenPolyfill
  23779. {
  23780. /** Get (exclusive) zero-based end position of the token. */
  23781. public function getEndPos(): int
  23782. {
  23783. return $this->pos + \strlen($this->text);
  23784. }
  23785. /** Get 1-based end line number of the token. */
  23786. public function getEndLine(): int
  23787. {
  23788. return $this->line + \substr_count($this->text, "\n");
  23789. }
  23790. }
  23791. <?php
  23792. declare (strict_types=1);
  23793. namespace PHPUnitPHAR\PhpParser;
  23794. if (!\function_exists('PHPUnitPHAR\PhpParser\defineCompatibilityTokens')) {
  23795. function defineCompatibilityTokens(): void
  23796. {
  23797. $compatTokens = [
  23798. // PHP 8.0
  23799. 'T_NAME_QUALIFIED',
  23800. 'T_NAME_FULLY_QUALIFIED',
  23801. 'T_NAME_RELATIVE',
  23802. 'T_MATCH',
  23803. 'T_NULLSAFE_OBJECT_OPERATOR',
  23804. 'T_ATTRIBUTE',
  23805. // PHP 8.1
  23806. 'T_ENUM',
  23807. 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG',
  23808. 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG',
  23809. 'T_READONLY',
  23810. // PHP 8.4
  23811. 'T_PROPERTY_C',
  23812. 'T_PUBLIC_SET',
  23813. 'T_PROTECTED_SET',
  23814. 'T_PRIVATE_SET',
  23815. ];
  23816. // PHP-Parser might be used together with another library that also emulates some or all
  23817. // of these tokens. Perform a sanity-check that all already defined tokens have been
  23818. // assigned a unique ID.
  23819. $usedTokenIds = [];
  23820. foreach ($compatTokens as $token) {
  23821. if (\defined($token)) {
  23822. $tokenId = \constant($token);
  23823. if (!\is_int($tokenId)) {
  23824. throw new \Error(sprintf('Token %s has ID of type %s, should be int. ' . 'You may be using a library with broken token emulation', $token, \gettype($tokenId)));
  23825. }
  23826. $clashingToken = $usedTokenIds[$tokenId] ?? null;
  23827. if ($clashingToken !== null) {
  23828. throw new \Error(sprintf('Token %s has same ID as token %s, ' . 'you may be using a library with broken token emulation', $token, $clashingToken));
  23829. }
  23830. $usedTokenIds[$tokenId] = $token;
  23831. }
  23832. }
  23833. // Now define any tokens that have not yet been emulated. Try to assign IDs from -1
  23834. // downwards, but skip any IDs that may already be in use.
  23835. $newTokenId = -1;
  23836. foreach ($compatTokens as $token) {
  23837. if (!\defined($token)) {
  23838. while (isset($usedTokenIds[$newTokenId])) {
  23839. $newTokenId--;
  23840. }
  23841. \define($token, $newTokenId);
  23842. $newTokenId--;
  23843. }
  23844. }
  23845. }
  23846. defineCompatibilityTokens();
  23847. }
  23848. BSD 3-Clause License
  23849. Copyright (c) 2016-2023, Sebastian Bergmann
  23850. All rights reserved.
  23851. Redistribution and use in source and binary forms, with or without
  23852. modification, are permitted provided that the following conditions are met:
  23853. 1. Redistributions of source code must retain the above copyright notice, this
  23854. list of conditions and the following disclaimer.
  23855. 2. Redistributions in binary form must reproduce the above copyright notice,
  23856. this list of conditions and the following disclaimer in the documentation
  23857. and/or other materials provided with the distribution.
  23858. 3. Neither the name of the copyright holder nor the names of its
  23859. contributors may be used to endorse or promote products derived from
  23860. this software without specific prior written permission.
  23861. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23862. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23863. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23864. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  23865. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23866. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23867. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23868. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23869. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23870. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23871. BSD 3-Clause License
  23872. Copyright (c) 2017-2023, Sebastian Bergmann
  23873. All rights reserved.
  23874. Redistribution and use in source and binary forms, with or without
  23875. modification, are permitted provided that the following conditions are met:
  23876. 1. Redistributions of source code must retain the above copyright notice, this
  23877. list of conditions and the following disclaimer.
  23878. 2. Redistributions in binary form must reproduce the above copyright notice,
  23879. this list of conditions and the following disclaimer in the documentation
  23880. and/or other materials provided with the distribution.
  23881. 3. Neither the name of the copyright holder nor the names of its
  23882. contributors may be used to endorse or promote products derived from
  23883. this software without specific prior written permission.
  23884. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23885. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23886. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23887. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  23888. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23889. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23890. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23891. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23892. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23893. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23894. Phar.io - Manifest
  23895. Copyright (c) 2016-2019 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>, and contributors
  23896. All rights reserved.
  23897. Redistribution and use in source and binary forms, with or without modification,
  23898. are permitted provided that the following conditions are met:
  23899. * Redistributions of source code must retain the above copyright notice,
  23900. this list of conditions and the following disclaimer.
  23901. * Redistributions in binary form must reproduce the above copyright notice,
  23902. this list of conditions and the following disclaimer in the documentation
  23903. and/or other materials provided with the distribution.
  23904. * Neither the name of Arne Blankerts nor the names of contributors
  23905. may be used to endorse or promote products derived from this software
  23906. without specific prior written permission.
  23907. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23908. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
  23909. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23910. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
  23911. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  23912. OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23913. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23914. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23915. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23916. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  23917. POSSIBILITY OF SUCH DAMAGE.
  23918. <?php
  23919. declare (strict_types=1);
  23920. /*
  23921. * This file is part of PharIo\Manifest.
  23922. *
  23923. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  23924. *
  23925. * For the full copyright and license information, please view the LICENSE
  23926. * file that was distributed with this source code.
  23927. *
  23928. */
  23929. namespace PHPUnitPHAR\PharIo\Manifest;
  23930. use PHPUnitPHAR\PharIo\Version\Exception as VersionException;
  23931. use PHPUnitPHAR\PharIo\Version\Version;
  23932. use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
  23933. use Throwable;
  23934. use function sprintf;
  23935. class ManifestDocumentMapper
  23936. {
  23937. public function map(ManifestDocument $document): Manifest
  23938. {
  23939. try {
  23940. $contains = $document->getContainsElement();
  23941. $type = $this->mapType($contains);
  23942. $copyright = $this->mapCopyright($document->getCopyrightElement());
  23943. $requirements = $this->mapRequirements($document->getRequiresElement());
  23944. $bundledComponents = $this->mapBundledComponents($document);
  23945. return new Manifest(new ApplicationName($contains->getName()), new Version($contains->getVersion()), $type, $copyright, $requirements, $bundledComponents);
  23946. } catch (Throwable $e) {
  23947. throw new ManifestDocumentMapperException($e->getMessage(), (int) $e->getCode(), $e);
  23948. }
  23949. }
  23950. private function mapType(ContainsElement $contains): Type
  23951. {
  23952. switch ($contains->getType()) {
  23953. case 'application':
  23954. return Type::application();
  23955. case 'library':
  23956. return Type::library();
  23957. case 'extension':
  23958. return $this->mapExtension($contains->getExtensionElement());
  23959. }
  23960. throw new ManifestDocumentMapperException(sprintf('Unsupported type %s', $contains->getType()));
  23961. }
  23962. private function mapCopyright(CopyrightElement $copyright): CopyrightInformation
  23963. {
  23964. $authors = new AuthorCollection();
  23965. foreach ($copyright->getAuthorElements() as $authorElement) {
  23966. $authors->add(new Author($authorElement->getName(), $authorElement->hasEMail() ? new Email($authorElement->getEmail()) : null));
  23967. }
  23968. $licenseElement = $copyright->getLicenseElement();
  23969. $license = new License($licenseElement->getType(), new Url($licenseElement->getUrl()));
  23970. return new CopyrightInformation($authors, $license);
  23971. }
  23972. private function mapRequirements(RequiresElement $requires): RequirementCollection
  23973. {
  23974. $collection = new RequirementCollection();
  23975. $phpElement = $requires->getPHPElement();
  23976. $parser = new VersionConstraintParser();
  23977. try {
  23978. $versionConstraint = $parser->parse($phpElement->getVersion());
  23979. } catch (VersionException $e) {
  23980. throw new ManifestDocumentMapperException(sprintf('Unsupported version constraint - %s', $e->getMessage()), (int) $e->getCode(), $e);
  23981. }
  23982. $collection->add(new PhpVersionRequirement($versionConstraint));
  23983. if (!$phpElement->hasExtElements()) {
  23984. return $collection;
  23985. }
  23986. foreach ($phpElement->getExtElements() as $extElement) {
  23987. $collection->add(new PhpExtensionRequirement($extElement->getName()));
  23988. }
  23989. return $collection;
  23990. }
  23991. private function mapBundledComponents(ManifestDocument $document): BundledComponentCollection
  23992. {
  23993. $collection = new BundledComponentCollection();
  23994. if (!$document->hasBundlesElement()) {
  23995. return $collection;
  23996. }
  23997. foreach ($document->getBundlesElement()->getComponentElements() as $componentElement) {
  23998. $collection->add(new BundledComponent($componentElement->getName(), new Version($componentElement->getVersion())));
  23999. }
  24000. return $collection;
  24001. }
  24002. private function mapExtension(ExtensionElement $extension): Extension
  24003. {
  24004. try {
  24005. $versionConstraint = (new VersionConstraintParser())->parse($extension->getCompatible());
  24006. return Type::extension(new ApplicationName($extension->getFor()), $versionConstraint);
  24007. } catch (VersionException $e) {
  24008. throw new ManifestDocumentMapperException(sprintf('Unsupported version constraint - %s', $e->getMessage()), (int) $e->getCode(), $e);
  24009. }
  24010. }
  24011. }
  24012. <?php
  24013. declare (strict_types=1);
  24014. /*
  24015. * This file is part of PharIo\Manifest.
  24016. *
  24017. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24018. *
  24019. * For the full copyright and license information, please view the LICENSE
  24020. * file that was distributed with this source code.
  24021. *
  24022. */
  24023. namespace PHPUnitPHAR\PharIo\Manifest;
  24024. use function sprintf;
  24025. class ManifestLoader
  24026. {
  24027. public static function fromFile(string $filename): Manifest
  24028. {
  24029. try {
  24030. return (new ManifestDocumentMapper())->map(ManifestDocument::fromFile($filename));
  24031. } catch (Exception $e) {
  24032. throw new ManifestLoaderException(sprintf('Loading %s failed.', $filename), (int) $e->getCode(), $e);
  24033. }
  24034. }
  24035. public static function fromPhar(string $filename): Manifest
  24036. {
  24037. return self::fromFile('phar://' . $filename . '/manifest.xml');
  24038. }
  24039. public static function fromString(string $manifest): Manifest
  24040. {
  24041. try {
  24042. return (new ManifestDocumentMapper())->map(ManifestDocument::fromString($manifest));
  24043. } catch (Exception $e) {
  24044. throw new ManifestLoaderException('Processing string failed', (int) $e->getCode(), $e);
  24045. }
  24046. }
  24047. }
  24048. <?php
  24049. declare (strict_types=1);
  24050. /*
  24051. * This file is part of PharIo\Manifest.
  24052. *
  24053. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24054. *
  24055. * For the full copyright and license information, please view the LICENSE
  24056. * file that was distributed with this source code.
  24057. *
  24058. */
  24059. namespace PHPUnitPHAR\PharIo\Manifest;
  24060. use PHPUnitPHAR\PharIo\Version\AnyVersionConstraint;
  24061. use PHPUnitPHAR\PharIo\Version\Version;
  24062. use PHPUnitPHAR\PharIo\Version\VersionConstraint;
  24063. use XMLWriter;
  24064. use function count;
  24065. use function file_put_contents;
  24066. use function str_repeat;
  24067. /** @psalm-suppress MissingConstructor */
  24068. class ManifestSerializer
  24069. {
  24070. /** @var XMLWriter */
  24071. private $xmlWriter;
  24072. public function serializeToFile(Manifest $manifest, string $filename): void
  24073. {
  24074. file_put_contents($filename, $this->serializeToString($manifest));
  24075. }
  24076. public function serializeToString(Manifest $manifest): string
  24077. {
  24078. $this->startDocument();
  24079. $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
  24080. $this->addCopyright($manifest->getCopyrightInformation());
  24081. $this->addRequirements($manifest->getRequirements());
  24082. $this->addBundles($manifest->getBundledComponents());
  24083. return $this->finishDocument();
  24084. }
  24085. private function startDocument(): void
  24086. {
  24087. $xmlWriter = new XMLWriter();
  24088. $xmlWriter->openMemory();
  24089. $xmlWriter->setIndent(\true);
  24090. $xmlWriter->setIndentString(str_repeat(' ', 4));
  24091. $xmlWriter->startDocument('1.0', 'UTF-8');
  24092. $xmlWriter->startElement('phar');
  24093. $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');
  24094. $this->xmlWriter = $xmlWriter;
  24095. }
  24096. private function finishDocument(): string
  24097. {
  24098. $this->xmlWriter->endElement();
  24099. $this->xmlWriter->endDocument();
  24100. return $this->xmlWriter->outputMemory();
  24101. }
  24102. private function addContains(ApplicationName $name, Version $version, Type $type): void
  24103. {
  24104. $this->xmlWriter->startElement('contains');
  24105. $this->xmlWriter->writeAttribute('name', $name->asString());
  24106. $this->xmlWriter->writeAttribute('version', $version->getVersionString());
  24107. switch (\true) {
  24108. case $type->isApplication():
  24109. {
  24110. $this->xmlWriter->writeAttribute('type', 'application');
  24111. break;
  24112. }
  24113. case $type->isLibrary():
  24114. {
  24115. $this->xmlWriter->writeAttribute('type', 'library');
  24116. break;
  24117. }
  24118. case $type->isExtension():
  24119. {
  24120. $this->xmlWriter->writeAttribute('type', 'extension');
  24121. /* @var $type Extension */
  24122. $this->addExtension($type->getApplicationName(), $type->getVersionConstraint());
  24123. break;
  24124. }
  24125. default:
  24126. {
  24127. $this->xmlWriter->writeAttribute('type', 'custom');
  24128. }
  24129. }
  24130. $this->xmlWriter->endElement();
  24131. }
  24132. private function addCopyright(CopyrightInformation $copyrightInformation): void
  24133. {
  24134. $this->xmlWriter->startElement('copyright');
  24135. foreach ($copyrightInformation->getAuthors() as $author) {
  24136. $this->xmlWriter->startElement('author');
  24137. $this->xmlWriter->writeAttribute('name', $author->getName());
  24138. $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString());
  24139. $this->xmlWriter->endElement();
  24140. }
  24141. $license = $copyrightInformation->getLicense();
  24142. $this->xmlWriter->startElement('license');
  24143. $this->xmlWriter->writeAttribute('type', $license->getName());
  24144. $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString());
  24145. $this->xmlWriter->endElement();
  24146. $this->xmlWriter->endElement();
  24147. }
  24148. private function addRequirements(RequirementCollection $requirementCollection): void
  24149. {
  24150. $phpRequirement = new AnyVersionConstraint();
  24151. $extensions = [];
  24152. foreach ($requirementCollection as $requirement) {
  24153. if ($requirement instanceof PhpVersionRequirement) {
  24154. $phpRequirement = $requirement->getVersionConstraint();
  24155. continue;
  24156. }
  24157. if ($requirement instanceof PhpExtensionRequirement) {
  24158. $extensions[] = $requirement->asString();
  24159. }
  24160. }
  24161. $this->xmlWriter->startElement('requires');
  24162. $this->xmlWriter->startElement('php');
  24163. $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());
  24164. foreach ($extensions as $extension) {
  24165. $this->xmlWriter->startElement('ext');
  24166. $this->xmlWriter->writeAttribute('name', $extension);
  24167. $this->xmlWriter->endElement();
  24168. }
  24169. $this->xmlWriter->endElement();
  24170. $this->xmlWriter->endElement();
  24171. }
  24172. private function addBundles(BundledComponentCollection $bundledComponentCollection): void
  24173. {
  24174. if (count($bundledComponentCollection) === 0) {
  24175. return;
  24176. }
  24177. $this->xmlWriter->startElement('bundles');
  24178. foreach ($bundledComponentCollection as $bundledComponent) {
  24179. $this->xmlWriter->startElement('component');
  24180. $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
  24181. $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
  24182. $this->xmlWriter->endElement();
  24183. }
  24184. $this->xmlWriter->endElement();
  24185. }
  24186. private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void
  24187. {
  24188. $this->xmlWriter->startElement('extension');
  24189. $this->xmlWriter->writeAttribute('for', $applicationName->asString());
  24190. $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
  24191. $this->xmlWriter->endElement();
  24192. }
  24193. }
  24194. <?php
  24195. declare (strict_types=1);
  24196. /*
  24197. * This file is part of PharIo\Manifest.
  24198. *
  24199. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24200. *
  24201. * For the full copyright and license information, please view the LICENSE
  24202. * file that was distributed with this source code.
  24203. *
  24204. */
  24205. namespace PHPUnitPHAR\PharIo\Manifest;
  24206. use InvalidArgumentException;
  24207. class ElementCollectionException extends InvalidArgumentException implements Exception
  24208. {
  24209. }
  24210. <?php
  24211. declare (strict_types=1);
  24212. /*
  24213. * This file is part of PharIo\Manifest.
  24214. *
  24215. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24216. *
  24217. * For the full copyright and license information, please view the LICENSE
  24218. * file that was distributed with this source code.
  24219. *
  24220. */
  24221. namespace PHPUnitPHAR\PharIo\Manifest;
  24222. use Throwable;
  24223. interface Exception extends Throwable
  24224. {
  24225. }
  24226. <?php
  24227. declare (strict_types=1);
  24228. /*
  24229. * This file is part of PharIo\Manifest.
  24230. *
  24231. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24232. *
  24233. * For the full copyright and license information, please view the LICENSE
  24234. * file that was distributed with this source code.
  24235. *
  24236. */
  24237. namespace PHPUnitPHAR\PharIo\Manifest;
  24238. use InvalidArgumentException;
  24239. class InvalidApplicationNameException extends InvalidArgumentException implements Exception
  24240. {
  24241. public const InvalidFormat = 2;
  24242. }
  24243. <?php
  24244. declare (strict_types=1);
  24245. /*
  24246. * This file is part of PharIo\Manifest.
  24247. *
  24248. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24249. *
  24250. * For the full copyright and license information, please view the LICENSE
  24251. * file that was distributed with this source code.
  24252. *
  24253. */
  24254. namespace PHPUnitPHAR\PharIo\Manifest;
  24255. use InvalidArgumentException;
  24256. class InvalidEmailException extends InvalidArgumentException implements Exception
  24257. {
  24258. }
  24259. <?php
  24260. declare (strict_types=1);
  24261. /*
  24262. * This file is part of PharIo\Manifest.
  24263. *
  24264. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24265. *
  24266. * For the full copyright and license information, please view the LICENSE
  24267. * file that was distributed with this source code.
  24268. *
  24269. */
  24270. namespace PHPUnitPHAR\PharIo\Manifest;
  24271. use InvalidArgumentException;
  24272. class InvalidUrlException extends InvalidArgumentException implements Exception
  24273. {
  24274. }
  24275. <?php
  24276. declare (strict_types=1);
  24277. /*
  24278. * This file is part of PharIo\Manifest.
  24279. *
  24280. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24281. *
  24282. * For the full copyright and license information, please view the LICENSE
  24283. * file that was distributed with this source code.
  24284. *
  24285. */
  24286. namespace PHPUnitPHAR\PharIo\Manifest;
  24287. use RuntimeException;
  24288. class ManifestDocumentException extends RuntimeException implements Exception
  24289. {
  24290. }
  24291. <?php
  24292. declare (strict_types=1);
  24293. /*
  24294. * This file is part of PharIo\Manifest.
  24295. *
  24296. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24297. *
  24298. * For the full copyright and license information, please view the LICENSE
  24299. * file that was distributed with this source code.
  24300. *
  24301. */
  24302. namespace PHPUnitPHAR\PharIo\Manifest;
  24303. use LibXMLError;
  24304. use function sprintf;
  24305. class ManifestDocumentLoadingException extends \Exception implements Exception
  24306. {
  24307. /** @var LibXMLError[] */
  24308. private $libxmlErrors;
  24309. /**
  24310. * ManifestDocumentLoadingException constructor.
  24311. *
  24312. * @param LibXMLError[] $libxmlErrors
  24313. */
  24314. public function __construct(array $libxmlErrors)
  24315. {
  24316. $this->libxmlErrors = $libxmlErrors;
  24317. $first = $this->libxmlErrors[0];
  24318. parent::__construct(sprintf('%s (Line: %d / Column: %d / File: %s)', $first->message, $first->line, $first->column, $first->file), $first->code);
  24319. }
  24320. /**
  24321. * @return LibXMLError[]
  24322. */
  24323. public function getLibxmlErrors(): array
  24324. {
  24325. return $this->libxmlErrors;
  24326. }
  24327. }
  24328. <?php
  24329. declare (strict_types=1);
  24330. /*
  24331. * This file is part of PharIo\Manifest.
  24332. *
  24333. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24334. *
  24335. * For the full copyright and license information, please view the LICENSE
  24336. * file that was distributed with this source code.
  24337. *
  24338. */
  24339. namespace PHPUnitPHAR\PharIo\Manifest;
  24340. use RuntimeException;
  24341. class ManifestDocumentMapperException extends RuntimeException implements Exception
  24342. {
  24343. }
  24344. <?php
  24345. declare (strict_types=1);
  24346. /*
  24347. * This file is part of PharIo\Manifest.
  24348. *
  24349. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24350. *
  24351. * For the full copyright and license information, please view the LICENSE
  24352. * file that was distributed with this source code.
  24353. *
  24354. */
  24355. namespace PHPUnitPHAR\PharIo\Manifest;
  24356. use RuntimeException;
  24357. class ManifestElementException extends RuntimeException implements Exception
  24358. {
  24359. }
  24360. <?php
  24361. declare (strict_types=1);
  24362. /*
  24363. * This file is part of PharIo\Manifest.
  24364. *
  24365. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24366. *
  24367. * For the full copyright and license information, please view the LICENSE
  24368. * file that was distributed with this source code.
  24369. *
  24370. */
  24371. namespace PHPUnitPHAR\PharIo\Manifest;
  24372. class ManifestLoaderException extends \Exception implements Exception
  24373. {
  24374. }
  24375. <?php
  24376. declare (strict_types=1);
  24377. /*
  24378. * This file is part of PharIo\Manifest.
  24379. *
  24380. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24381. *
  24382. * For the full copyright and license information, please view the LICENSE
  24383. * file that was distributed with this source code.
  24384. *
  24385. */
  24386. namespace PHPUnitPHAR\PharIo\Manifest;
  24387. use InvalidArgumentException;
  24388. class NoEmailAddressException extends InvalidArgumentException implements Exception
  24389. {
  24390. }
  24391. <?php
  24392. declare (strict_types=1);
  24393. /*
  24394. * This file is part of PharIo\Manifest.
  24395. *
  24396. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24397. *
  24398. * For the full copyright and license information, please view the LICENSE
  24399. * file that was distributed with this source code.
  24400. *
  24401. */
  24402. namespace PHPUnitPHAR\PharIo\Manifest;
  24403. class Application extends Type
  24404. {
  24405. public function isApplication(): bool
  24406. {
  24407. return \true;
  24408. }
  24409. }
  24410. <?php
  24411. declare (strict_types=1);
  24412. /*
  24413. * This file is part of PharIo\Manifest.
  24414. *
  24415. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24416. *
  24417. * For the full copyright and license information, please view the LICENSE
  24418. * file that was distributed with this source code.
  24419. *
  24420. */
  24421. namespace PHPUnitPHAR\PharIo\Manifest;
  24422. use function preg_match;
  24423. use function sprintf;
  24424. class ApplicationName
  24425. {
  24426. /** @var string */
  24427. private $name;
  24428. public function __construct(string $name)
  24429. {
  24430. $this->ensureValidFormat($name);
  24431. $this->name = $name;
  24432. }
  24433. public function asString(): string
  24434. {
  24435. return $this->name;
  24436. }
  24437. public function isEqual(ApplicationName $name): bool
  24438. {
  24439. return $this->name === $name->name;
  24440. }
  24441. private function ensureValidFormat(string $name): void
  24442. {
  24443. if (!preg_match('#\w/\w#', $name)) {
  24444. throw new InvalidApplicationNameException(sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name), InvalidApplicationNameException::InvalidFormat);
  24445. }
  24446. }
  24447. }
  24448. <?php
  24449. declare (strict_types=1);
  24450. /*
  24451. * This file is part of PharIo\Manifest.
  24452. *
  24453. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24454. *
  24455. * For the full copyright and license information, please view the LICENSE
  24456. * file that was distributed with this source code.
  24457. *
  24458. */
  24459. namespace PHPUnitPHAR\PharIo\Manifest;
  24460. use function sprintf;
  24461. class Author
  24462. {
  24463. /** @var string */
  24464. private $name;
  24465. /** @var null|Email */
  24466. private $email;
  24467. public function __construct(string $name, ?Email $email = null)
  24468. {
  24469. $this->name = $name;
  24470. $this->email = $email;
  24471. }
  24472. public function asString(): string
  24473. {
  24474. if (!$this->hasEmail()) {
  24475. return $this->name;
  24476. }
  24477. return sprintf('%s <%s>', $this->name, $this->email->asString());
  24478. }
  24479. public function getName(): string
  24480. {
  24481. return $this->name;
  24482. }
  24483. /**
  24484. * @psalm-assert-if-true Email $this->email
  24485. */
  24486. public function hasEmail(): bool
  24487. {
  24488. return $this->email !== null;
  24489. }
  24490. public function getEmail(): Email
  24491. {
  24492. if (!$this->hasEmail()) {
  24493. throw new NoEmailAddressException();
  24494. }
  24495. return $this->email;
  24496. }
  24497. }
  24498. <?php
  24499. declare (strict_types=1);
  24500. /*
  24501. * This file is part of PharIo\Manifest.
  24502. *
  24503. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24504. *
  24505. * For the full copyright and license information, please view the LICENSE
  24506. * file that was distributed with this source code.
  24507. *
  24508. */
  24509. namespace PHPUnitPHAR\PharIo\Manifest;
  24510. use Countable;
  24511. use IteratorAggregate;
  24512. use function count;
  24513. /** @template-implements IteratorAggregate<int,Author> */
  24514. class AuthorCollection implements Countable, IteratorAggregate
  24515. {
  24516. /** @var Author[] */
  24517. private $authors = [];
  24518. public function add(Author $author): void
  24519. {
  24520. $this->authors[] = $author;
  24521. }
  24522. /**
  24523. * @return Author[]
  24524. */
  24525. public function getAuthors(): array
  24526. {
  24527. return $this->authors;
  24528. }
  24529. public function count(): int
  24530. {
  24531. return count($this->authors);
  24532. }
  24533. public function getIterator(): AuthorCollectionIterator
  24534. {
  24535. return new AuthorCollectionIterator($this);
  24536. }
  24537. }
  24538. <?php
  24539. declare (strict_types=1);
  24540. /*
  24541. * This file is part of PharIo\Manifest.
  24542. *
  24543. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24544. *
  24545. * For the full copyright and license information, please view the LICENSE
  24546. * file that was distributed with this source code.
  24547. *
  24548. */
  24549. namespace PHPUnitPHAR\PharIo\Manifest;
  24550. use Iterator;
  24551. use function count;
  24552. /** @template-implements Iterator<int,Author> */
  24553. class AuthorCollectionIterator implements Iterator
  24554. {
  24555. /** @var Author[] */
  24556. private $authors;
  24557. /** @var int */
  24558. private $position = 0;
  24559. public function __construct(AuthorCollection $authors)
  24560. {
  24561. $this->authors = $authors->getAuthors();
  24562. }
  24563. public function rewind(): void
  24564. {
  24565. $this->position = 0;
  24566. }
  24567. public function valid(): bool
  24568. {
  24569. return $this->position < count($this->authors);
  24570. }
  24571. public function key(): int
  24572. {
  24573. return $this->position;
  24574. }
  24575. public function current(): Author
  24576. {
  24577. return $this->authors[$this->position];
  24578. }
  24579. public function next(): void
  24580. {
  24581. $this->position++;
  24582. }
  24583. }
  24584. <?php
  24585. declare (strict_types=1);
  24586. /*
  24587. * This file is part of PharIo\Manifest.
  24588. *
  24589. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24590. *
  24591. * For the full copyright and license information, please view the LICENSE
  24592. * file that was distributed with this source code.
  24593. *
  24594. */
  24595. namespace PHPUnitPHAR\PharIo\Manifest;
  24596. use PHPUnitPHAR\PharIo\Version\Version;
  24597. class BundledComponent
  24598. {
  24599. /** @var string */
  24600. private $name;
  24601. /** @var Version */
  24602. private $version;
  24603. public function __construct(string $name, Version $version)
  24604. {
  24605. $this->name = $name;
  24606. $this->version = $version;
  24607. }
  24608. public function getName(): string
  24609. {
  24610. return $this->name;
  24611. }
  24612. public function getVersion(): Version
  24613. {
  24614. return $this->version;
  24615. }
  24616. }
  24617. <?php
  24618. declare (strict_types=1);
  24619. /*
  24620. * This file is part of PharIo\Manifest.
  24621. *
  24622. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24623. *
  24624. * For the full copyright and license information, please view the LICENSE
  24625. * file that was distributed with this source code.
  24626. *
  24627. */
  24628. namespace PHPUnitPHAR\PharIo\Manifest;
  24629. use Countable;
  24630. use IteratorAggregate;
  24631. use function count;
  24632. /** @template-implements IteratorAggregate<int,BundledComponent> */
  24633. class BundledComponentCollection implements Countable, IteratorAggregate
  24634. {
  24635. /** @var BundledComponent[] */
  24636. private $bundledComponents = [];
  24637. public function add(BundledComponent $bundledComponent): void
  24638. {
  24639. $this->bundledComponents[] = $bundledComponent;
  24640. }
  24641. /**
  24642. * @return BundledComponent[]
  24643. */
  24644. public function getBundledComponents(): array
  24645. {
  24646. return $this->bundledComponents;
  24647. }
  24648. public function count(): int
  24649. {
  24650. return count($this->bundledComponents);
  24651. }
  24652. public function getIterator(): BundledComponentCollectionIterator
  24653. {
  24654. return new BundledComponentCollectionIterator($this);
  24655. }
  24656. }
  24657. <?php
  24658. declare (strict_types=1);
  24659. /*
  24660. * This file is part of PharIo\Manifest.
  24661. *
  24662. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24663. *
  24664. * For the full copyright and license information, please view the LICENSE
  24665. * file that was distributed with this source code.
  24666. *
  24667. */
  24668. namespace PHPUnitPHAR\PharIo\Manifest;
  24669. use Iterator;
  24670. use function count;
  24671. /** @template-implements Iterator<int,BundledComponent> */
  24672. class BundledComponentCollectionIterator implements Iterator
  24673. {
  24674. /** @var BundledComponent[] */
  24675. private $bundledComponents;
  24676. /** @var int */
  24677. private $position = 0;
  24678. public function __construct(BundledComponentCollection $bundledComponents)
  24679. {
  24680. $this->bundledComponents = $bundledComponents->getBundledComponents();
  24681. }
  24682. public function rewind(): void
  24683. {
  24684. $this->position = 0;
  24685. }
  24686. public function valid(): bool
  24687. {
  24688. return $this->position < count($this->bundledComponents);
  24689. }
  24690. public function key(): int
  24691. {
  24692. return $this->position;
  24693. }
  24694. public function current(): BundledComponent
  24695. {
  24696. return $this->bundledComponents[$this->position];
  24697. }
  24698. public function next(): void
  24699. {
  24700. $this->position++;
  24701. }
  24702. }
  24703. <?php
  24704. declare (strict_types=1);
  24705. /*
  24706. * This file is part of PharIo\Manifest.
  24707. *
  24708. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24709. *
  24710. * For the full copyright and license information, please view the LICENSE
  24711. * file that was distributed with this source code.
  24712. *
  24713. */
  24714. namespace PHPUnitPHAR\PharIo\Manifest;
  24715. class CopyrightInformation
  24716. {
  24717. /** @var AuthorCollection */
  24718. private $authors;
  24719. /** @var License */
  24720. private $license;
  24721. public function __construct(AuthorCollection $authors, License $license)
  24722. {
  24723. $this->authors = $authors;
  24724. $this->license = $license;
  24725. }
  24726. public function getAuthors(): AuthorCollection
  24727. {
  24728. return $this->authors;
  24729. }
  24730. public function getLicense(): License
  24731. {
  24732. return $this->license;
  24733. }
  24734. }
  24735. <?php
  24736. declare (strict_types=1);
  24737. /*
  24738. * This file is part of PharIo\Manifest.
  24739. *
  24740. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24741. *
  24742. * For the full copyright and license information, please view the LICENSE
  24743. * file that was distributed with this source code.
  24744. *
  24745. */
  24746. namespace PHPUnitPHAR\PharIo\Manifest;
  24747. use const FILTER_VALIDATE_EMAIL;
  24748. use function filter_var;
  24749. class Email
  24750. {
  24751. /** @var string */
  24752. private $email;
  24753. public function __construct(string $email)
  24754. {
  24755. $this->ensureEmailIsValid($email);
  24756. $this->email = $email;
  24757. }
  24758. public function asString(): string
  24759. {
  24760. return $this->email;
  24761. }
  24762. private function ensureEmailIsValid(string $url): void
  24763. {
  24764. if (filter_var($url, FILTER_VALIDATE_EMAIL) === \false) {
  24765. throw new InvalidEmailException();
  24766. }
  24767. }
  24768. }
  24769. <?php
  24770. declare (strict_types=1);
  24771. /*
  24772. * This file is part of PharIo\Manifest.
  24773. *
  24774. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24775. *
  24776. * For the full copyright and license information, please view the LICENSE
  24777. * file that was distributed with this source code.
  24778. *
  24779. */
  24780. namespace PHPUnitPHAR\PharIo\Manifest;
  24781. use PHPUnitPHAR\PharIo\Version\Version;
  24782. use PHPUnitPHAR\PharIo\Version\VersionConstraint;
  24783. class Extension extends Type
  24784. {
  24785. /** @var ApplicationName */
  24786. private $application;
  24787. /** @var VersionConstraint */
  24788. private $versionConstraint;
  24789. public function __construct(ApplicationName $application, VersionConstraint $versionConstraint)
  24790. {
  24791. $this->application = $application;
  24792. $this->versionConstraint = $versionConstraint;
  24793. }
  24794. public function getApplicationName(): ApplicationName
  24795. {
  24796. return $this->application;
  24797. }
  24798. public function getVersionConstraint(): VersionConstraint
  24799. {
  24800. return $this->versionConstraint;
  24801. }
  24802. public function isExtension(): bool
  24803. {
  24804. return \true;
  24805. }
  24806. public function isExtensionFor(ApplicationName $name): bool
  24807. {
  24808. return $this->application->isEqual($name);
  24809. }
  24810. public function isCompatibleWith(ApplicationName $name, Version $version): bool
  24811. {
  24812. return $this->isExtensionFor($name) && $this->versionConstraint->complies($version);
  24813. }
  24814. }
  24815. <?php
  24816. declare (strict_types=1);
  24817. /*
  24818. * This file is part of PharIo\Manifest.
  24819. *
  24820. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24821. *
  24822. * For the full copyright and license information, please view the LICENSE
  24823. * file that was distributed with this source code.
  24824. *
  24825. */
  24826. namespace PHPUnitPHAR\PharIo\Manifest;
  24827. class Library extends Type
  24828. {
  24829. public function isLibrary(): bool
  24830. {
  24831. return \true;
  24832. }
  24833. }
  24834. <?php
  24835. declare (strict_types=1);
  24836. /*
  24837. * This file is part of PharIo\Manifest.
  24838. *
  24839. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24840. *
  24841. * For the full copyright and license information, please view the LICENSE
  24842. * file that was distributed with this source code.
  24843. *
  24844. */
  24845. namespace PHPUnitPHAR\PharIo\Manifest;
  24846. class License
  24847. {
  24848. /** @var string */
  24849. private $name;
  24850. /** @var Url */
  24851. private $url;
  24852. public function __construct(string $name, Url $url)
  24853. {
  24854. $this->name = $name;
  24855. $this->url = $url;
  24856. }
  24857. public function getName(): string
  24858. {
  24859. return $this->name;
  24860. }
  24861. public function getUrl(): Url
  24862. {
  24863. return $this->url;
  24864. }
  24865. }
  24866. <?php
  24867. declare (strict_types=1);
  24868. /*
  24869. * This file is part of PharIo\Manifest.
  24870. *
  24871. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24872. *
  24873. * For the full copyright and license information, please view the LICENSE
  24874. * file that was distributed with this source code.
  24875. *
  24876. */
  24877. namespace PHPUnitPHAR\PharIo\Manifest;
  24878. use PHPUnitPHAR\PharIo\Version\Version;
  24879. class Manifest
  24880. {
  24881. /** @var ApplicationName */
  24882. private $name;
  24883. /** @var Version */
  24884. private $version;
  24885. /** @var Type */
  24886. private $type;
  24887. /** @var CopyrightInformation */
  24888. private $copyrightInformation;
  24889. /** @var RequirementCollection */
  24890. private $requirements;
  24891. /** @var BundledComponentCollection */
  24892. private $bundledComponents;
  24893. public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents)
  24894. {
  24895. $this->name = $name;
  24896. $this->version = $version;
  24897. $this->type = $type;
  24898. $this->copyrightInformation = $copyrightInformation;
  24899. $this->requirements = $requirements;
  24900. $this->bundledComponents = $bundledComponents;
  24901. }
  24902. public function getName(): ApplicationName
  24903. {
  24904. return $this->name;
  24905. }
  24906. public function getVersion(): Version
  24907. {
  24908. return $this->version;
  24909. }
  24910. public function getType(): Type
  24911. {
  24912. return $this->type;
  24913. }
  24914. public function getCopyrightInformation(): CopyrightInformation
  24915. {
  24916. return $this->copyrightInformation;
  24917. }
  24918. public function getRequirements(): RequirementCollection
  24919. {
  24920. return $this->requirements;
  24921. }
  24922. public function getBundledComponents(): BundledComponentCollection
  24923. {
  24924. return $this->bundledComponents;
  24925. }
  24926. public function isApplication(): bool
  24927. {
  24928. return $this->type->isApplication();
  24929. }
  24930. public function isLibrary(): bool
  24931. {
  24932. return $this->type->isLibrary();
  24933. }
  24934. public function isExtension(): bool
  24935. {
  24936. return $this->type->isExtension();
  24937. }
  24938. public function isExtensionFor(ApplicationName $application, ?Version $version = null): bool
  24939. {
  24940. if (!$this->isExtension()) {
  24941. return \false;
  24942. }
  24943. /** @var Extension $type */
  24944. $type = $this->type;
  24945. if ($version !== null) {
  24946. return $type->isCompatibleWith($application, $version);
  24947. }
  24948. return $type->isExtensionFor($application);
  24949. }
  24950. }
  24951. <?php
  24952. declare (strict_types=1);
  24953. /*
  24954. * This file is part of PharIo\Manifest.
  24955. *
  24956. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24957. *
  24958. * For the full copyright and license information, please view the LICENSE
  24959. * file that was distributed with this source code.
  24960. *
  24961. */
  24962. namespace PHPUnitPHAR\PharIo\Manifest;
  24963. class PhpExtensionRequirement implements Requirement
  24964. {
  24965. /** @var string */
  24966. private $extension;
  24967. public function __construct(string $extension)
  24968. {
  24969. $this->extension = $extension;
  24970. }
  24971. public function asString(): string
  24972. {
  24973. return $this->extension;
  24974. }
  24975. }
  24976. <?php
  24977. declare (strict_types=1);
  24978. /*
  24979. * This file is part of PharIo\Manifest.
  24980. *
  24981. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  24982. *
  24983. * For the full copyright and license information, please view the LICENSE
  24984. * file that was distributed with this source code.
  24985. *
  24986. */
  24987. namespace PHPUnitPHAR\PharIo\Manifest;
  24988. use PHPUnitPHAR\PharIo\Version\VersionConstraint;
  24989. class PhpVersionRequirement implements Requirement
  24990. {
  24991. /** @var VersionConstraint */
  24992. private $versionConstraint;
  24993. public function __construct(VersionConstraint $versionConstraint)
  24994. {
  24995. $this->versionConstraint = $versionConstraint;
  24996. }
  24997. public function getVersionConstraint(): VersionConstraint
  24998. {
  24999. return $this->versionConstraint;
  25000. }
  25001. }
  25002. <?php
  25003. declare (strict_types=1);
  25004. /*
  25005. * This file is part of PharIo\Manifest.
  25006. *
  25007. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25008. *
  25009. * For the full copyright and license information, please view the LICENSE
  25010. * file that was distributed with this source code.
  25011. *
  25012. */
  25013. namespace PHPUnitPHAR\PharIo\Manifest;
  25014. interface Requirement
  25015. {
  25016. }
  25017. <?php
  25018. declare (strict_types=1);
  25019. /*
  25020. * This file is part of PharIo\Manifest.
  25021. *
  25022. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25023. *
  25024. * For the full copyright and license information, please view the LICENSE
  25025. * file that was distributed with this source code.
  25026. *
  25027. */
  25028. namespace PHPUnitPHAR\PharIo\Manifest;
  25029. use Countable;
  25030. use IteratorAggregate;
  25031. use function count;
  25032. /** @template-implements IteratorAggregate<int,Requirement> */
  25033. class RequirementCollection implements Countable, IteratorAggregate
  25034. {
  25035. /** @var Requirement[] */
  25036. private $requirements = [];
  25037. public function add(Requirement $requirement): void
  25038. {
  25039. $this->requirements[] = $requirement;
  25040. }
  25041. /**
  25042. * @return Requirement[]
  25043. */
  25044. public function getRequirements(): array
  25045. {
  25046. return $this->requirements;
  25047. }
  25048. public function count(): int
  25049. {
  25050. return count($this->requirements);
  25051. }
  25052. public function getIterator(): RequirementCollectionIterator
  25053. {
  25054. return new RequirementCollectionIterator($this);
  25055. }
  25056. }
  25057. <?php
  25058. declare (strict_types=1);
  25059. /*
  25060. * This file is part of PharIo\Manifest.
  25061. *
  25062. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25063. *
  25064. * For the full copyright and license information, please view the LICENSE
  25065. * file that was distributed with this source code.
  25066. *
  25067. */
  25068. namespace PHPUnitPHAR\PharIo\Manifest;
  25069. use Iterator;
  25070. use function count;
  25071. /** @template-implements Iterator<int,Requirement> */
  25072. class RequirementCollectionIterator implements Iterator
  25073. {
  25074. /** @var Requirement[] */
  25075. private $requirements;
  25076. /** @var int */
  25077. private $position = 0;
  25078. public function __construct(RequirementCollection $requirements)
  25079. {
  25080. $this->requirements = $requirements->getRequirements();
  25081. }
  25082. public function rewind(): void
  25083. {
  25084. $this->position = 0;
  25085. }
  25086. public function valid(): bool
  25087. {
  25088. return $this->position < count($this->requirements);
  25089. }
  25090. public function key(): int
  25091. {
  25092. return $this->position;
  25093. }
  25094. public function current(): Requirement
  25095. {
  25096. return $this->requirements[$this->position];
  25097. }
  25098. public function next(): void
  25099. {
  25100. $this->position++;
  25101. }
  25102. }
  25103. <?php
  25104. declare (strict_types=1);
  25105. /*
  25106. * This file is part of PharIo\Manifest.
  25107. *
  25108. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25109. *
  25110. * For the full copyright and license information, please view the LICENSE
  25111. * file that was distributed with this source code.
  25112. *
  25113. */
  25114. namespace PHPUnitPHAR\PharIo\Manifest;
  25115. use PHPUnitPHAR\PharIo\Version\VersionConstraint;
  25116. abstract class Type
  25117. {
  25118. public static function application(): Application
  25119. {
  25120. return new Application();
  25121. }
  25122. public static function library(): Library
  25123. {
  25124. return new Library();
  25125. }
  25126. public static function extension(ApplicationName $application, VersionConstraint $versionConstraint): Extension
  25127. {
  25128. return new Extension($application, $versionConstraint);
  25129. }
  25130. /** @psalm-assert-if-true Application $this */
  25131. public function isApplication(): bool
  25132. {
  25133. return \false;
  25134. }
  25135. /** @psalm-assert-if-true Library $this */
  25136. public function isLibrary(): bool
  25137. {
  25138. return \false;
  25139. }
  25140. /** @psalm-assert-if-true Extension $this */
  25141. public function isExtension(): bool
  25142. {
  25143. return \false;
  25144. }
  25145. }
  25146. <?php
  25147. declare (strict_types=1);
  25148. /*
  25149. * This file is part of PharIo\Manifest.
  25150. *
  25151. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25152. *
  25153. * For the full copyright and license information, please view the LICENSE
  25154. * file that was distributed with this source code.
  25155. *
  25156. */
  25157. namespace PHPUnitPHAR\PharIo\Manifest;
  25158. use const FILTER_VALIDATE_URL;
  25159. use function filter_var;
  25160. class Url
  25161. {
  25162. /** @var string */
  25163. private $url;
  25164. public function __construct(string $url)
  25165. {
  25166. $this->ensureUrlIsValid($url);
  25167. $this->url = $url;
  25168. }
  25169. public function asString(): string
  25170. {
  25171. return $this->url;
  25172. }
  25173. /**
  25174. * @throws InvalidUrlException
  25175. */
  25176. private function ensureUrlIsValid(string $url): void
  25177. {
  25178. if (filter_var($url, FILTER_VALIDATE_URL) === \false) {
  25179. throw new InvalidUrlException();
  25180. }
  25181. }
  25182. }
  25183. <?php
  25184. declare (strict_types=1);
  25185. /*
  25186. * This file is part of PharIo\Manifest.
  25187. *
  25188. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25189. *
  25190. * For the full copyright and license information, please view the LICENSE
  25191. * file that was distributed with this source code.
  25192. *
  25193. */
  25194. namespace PHPUnitPHAR\PharIo\Manifest;
  25195. class AuthorElement extends ManifestElement
  25196. {
  25197. public function getName(): string
  25198. {
  25199. return $this->getAttributeValue('name');
  25200. }
  25201. public function getEmail(): string
  25202. {
  25203. return $this->getAttributeValue('email');
  25204. }
  25205. public function hasEMail(): bool
  25206. {
  25207. return $this->hasAttribute('email');
  25208. }
  25209. }
  25210. <?php
  25211. declare (strict_types=1);
  25212. /*
  25213. * This file is part of PharIo\Manifest.
  25214. *
  25215. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25216. *
  25217. * For the full copyright and license information, please view the LICENSE
  25218. * file that was distributed with this source code.
  25219. *
  25220. */
  25221. namespace PHPUnitPHAR\PharIo\Manifest;
  25222. class AuthorElementCollection extends ElementCollection
  25223. {
  25224. public function current(): AuthorElement
  25225. {
  25226. return new AuthorElement($this->getCurrentElement());
  25227. }
  25228. }
  25229. <?php
  25230. declare (strict_types=1);
  25231. /*
  25232. * This file is part of PharIo\Manifest.
  25233. *
  25234. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25235. *
  25236. * For the full copyright and license information, please view the LICENSE
  25237. * file that was distributed with this source code.
  25238. *
  25239. */
  25240. namespace PHPUnitPHAR\PharIo\Manifest;
  25241. class BundlesElement extends ManifestElement
  25242. {
  25243. public function getComponentElements(): ComponentElementCollection
  25244. {
  25245. return new ComponentElementCollection($this->getChildrenByName('component'));
  25246. }
  25247. }
  25248. <?php
  25249. declare (strict_types=1);
  25250. /*
  25251. * This file is part of PharIo\Manifest.
  25252. *
  25253. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25254. *
  25255. * For the full copyright and license information, please view the LICENSE
  25256. * file that was distributed with this source code.
  25257. *
  25258. */
  25259. namespace PHPUnitPHAR\PharIo\Manifest;
  25260. class ComponentElement extends ManifestElement
  25261. {
  25262. public function getName(): string
  25263. {
  25264. return $this->getAttributeValue('name');
  25265. }
  25266. public function getVersion(): string
  25267. {
  25268. return $this->getAttributeValue('version');
  25269. }
  25270. }
  25271. <?php
  25272. declare (strict_types=1);
  25273. /*
  25274. * This file is part of PharIo\Manifest.
  25275. *
  25276. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25277. *
  25278. * For the full copyright and license information, please view the LICENSE
  25279. * file that was distributed with this source code.
  25280. *
  25281. */
  25282. namespace PHPUnitPHAR\PharIo\Manifest;
  25283. class ComponentElementCollection extends ElementCollection
  25284. {
  25285. public function current(): ComponentElement
  25286. {
  25287. return new ComponentElement($this->getCurrentElement());
  25288. }
  25289. }
  25290. <?php
  25291. declare (strict_types=1);
  25292. /*
  25293. * This file is part of PharIo\Manifest.
  25294. *
  25295. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25296. *
  25297. * For the full copyright and license information, please view the LICENSE
  25298. * file that was distributed with this source code.
  25299. *
  25300. */
  25301. namespace PHPUnitPHAR\PharIo\Manifest;
  25302. class ContainsElement extends ManifestElement
  25303. {
  25304. public function getName(): string
  25305. {
  25306. return $this->getAttributeValue('name');
  25307. }
  25308. public function getVersion(): string
  25309. {
  25310. return $this->getAttributeValue('version');
  25311. }
  25312. public function getType(): string
  25313. {
  25314. return $this->getAttributeValue('type');
  25315. }
  25316. public function getExtensionElement(): ExtensionElement
  25317. {
  25318. return new ExtensionElement($this->getChildByName('extension'));
  25319. }
  25320. }
  25321. <?php
  25322. declare (strict_types=1);
  25323. /*
  25324. * This file is part of PharIo\Manifest.
  25325. *
  25326. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25327. *
  25328. * For the full copyright and license information, please view the LICENSE
  25329. * file that was distributed with this source code.
  25330. *
  25331. */
  25332. namespace PHPUnitPHAR\PharIo\Manifest;
  25333. class CopyrightElement extends ManifestElement
  25334. {
  25335. public function getAuthorElements(): AuthorElementCollection
  25336. {
  25337. return new AuthorElementCollection($this->getChildrenByName('author'));
  25338. }
  25339. public function getLicenseElement(): LicenseElement
  25340. {
  25341. return new LicenseElement($this->getChildByName('license'));
  25342. }
  25343. }
  25344. <?php
  25345. declare (strict_types=1);
  25346. /*
  25347. * This file is part of PharIo\Manifest.
  25348. *
  25349. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25350. *
  25351. * For the full copyright and license information, please view the LICENSE
  25352. * file that was distributed with this source code.
  25353. *
  25354. */
  25355. namespace PHPUnitPHAR\PharIo\Manifest;
  25356. use DOMElement;
  25357. use DOMNodeList;
  25358. use Iterator;
  25359. use ReturnTypeWillChange;
  25360. use function count;
  25361. use function get_class;
  25362. use function sprintf;
  25363. /** @template-implements Iterator<int,DOMElement> */
  25364. abstract class ElementCollection implements Iterator
  25365. {
  25366. /** @var DOMElement[] */
  25367. private $nodes = [];
  25368. /** @var int */
  25369. private $position;
  25370. public function __construct(DOMNodeList $nodeList)
  25371. {
  25372. $this->position = 0;
  25373. $this->importNodes($nodeList);
  25374. }
  25375. #[ReturnTypeWillChange]
  25376. abstract public function current();
  25377. public function next(): void
  25378. {
  25379. $this->position++;
  25380. }
  25381. public function key(): int
  25382. {
  25383. return $this->position;
  25384. }
  25385. public function valid(): bool
  25386. {
  25387. return $this->position < count($this->nodes);
  25388. }
  25389. public function rewind(): void
  25390. {
  25391. $this->position = 0;
  25392. }
  25393. protected function getCurrentElement(): DOMElement
  25394. {
  25395. return $this->nodes[$this->position];
  25396. }
  25397. private function importNodes(DOMNodeList $nodeList): void
  25398. {
  25399. foreach ($nodeList as $node) {
  25400. if (!$node instanceof DOMElement) {
  25401. throw new ElementCollectionException(sprintf('\DOMElement expected, got \%s', get_class($node)));
  25402. }
  25403. $this->nodes[] = $node;
  25404. }
  25405. }
  25406. }
  25407. <?php
  25408. declare (strict_types=1);
  25409. /*
  25410. * This file is part of PharIo\Manifest.
  25411. *
  25412. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25413. *
  25414. * For the full copyright and license information, please view the LICENSE
  25415. * file that was distributed with this source code.
  25416. *
  25417. */
  25418. namespace PHPUnitPHAR\PharIo\Manifest;
  25419. class ExtElement extends ManifestElement
  25420. {
  25421. public function getName(): string
  25422. {
  25423. return $this->getAttributeValue('name');
  25424. }
  25425. }
  25426. <?php
  25427. declare (strict_types=1);
  25428. /*
  25429. * This file is part of PharIo\Manifest.
  25430. *
  25431. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25432. *
  25433. * For the full copyright and license information, please view the LICENSE
  25434. * file that was distributed with this source code.
  25435. *
  25436. */
  25437. namespace PHPUnitPHAR\PharIo\Manifest;
  25438. class ExtElementCollection extends ElementCollection
  25439. {
  25440. public function current(): ExtElement
  25441. {
  25442. return new ExtElement($this->getCurrentElement());
  25443. }
  25444. }
  25445. <?php
  25446. declare (strict_types=1);
  25447. /*
  25448. * This file is part of PharIo\Manifest.
  25449. *
  25450. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25451. *
  25452. * For the full copyright and license information, please view the LICENSE
  25453. * file that was distributed with this source code.
  25454. *
  25455. */
  25456. namespace PHPUnitPHAR\PharIo\Manifest;
  25457. class ExtensionElement extends ManifestElement
  25458. {
  25459. public function getFor(): string
  25460. {
  25461. return $this->getAttributeValue('for');
  25462. }
  25463. public function getCompatible(): string
  25464. {
  25465. return $this->getAttributeValue('compatible');
  25466. }
  25467. }
  25468. <?php
  25469. declare (strict_types=1);
  25470. /*
  25471. * This file is part of PharIo\Manifest.
  25472. *
  25473. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25474. *
  25475. * For the full copyright and license information, please view the LICENSE
  25476. * file that was distributed with this source code.
  25477. *
  25478. */
  25479. namespace PHPUnitPHAR\PharIo\Manifest;
  25480. class LicenseElement extends ManifestElement
  25481. {
  25482. public function getType(): string
  25483. {
  25484. return $this->getAttributeValue('type');
  25485. }
  25486. public function getUrl(): string
  25487. {
  25488. return $this->getAttributeValue('url');
  25489. }
  25490. }
  25491. <?php
  25492. declare (strict_types=1);
  25493. /*
  25494. * This file is part of PharIo\Manifest.
  25495. *
  25496. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25497. *
  25498. * For the full copyright and license information, please view the LICENSE
  25499. * file that was distributed with this source code.
  25500. *
  25501. */
  25502. namespace PHPUnitPHAR\PharIo\Manifest;
  25503. use DOMDocument;
  25504. use DOMElement;
  25505. use Throwable;
  25506. use function count;
  25507. use function file_get_contents;
  25508. use function is_file;
  25509. use function libxml_clear_errors;
  25510. use function libxml_get_errors;
  25511. use function libxml_use_internal_errors;
  25512. use function sprintf;
  25513. class ManifestDocument
  25514. {
  25515. public const XMLNS = 'https://phar.io/xml/manifest/1.0';
  25516. /** @var DOMDocument */
  25517. private $dom;
  25518. public static function fromFile(string $filename): ManifestDocument
  25519. {
  25520. if (!is_file($filename)) {
  25521. throw new ManifestDocumentException(sprintf('File "%s" not found', $filename));
  25522. }
  25523. return self::fromString(file_get_contents($filename));
  25524. }
  25525. public static function fromString(string $xmlString): ManifestDocument
  25526. {
  25527. $prev = libxml_use_internal_errors(\true);
  25528. libxml_clear_errors();
  25529. try {
  25530. $dom = new DOMDocument();
  25531. $dom->loadXML($xmlString);
  25532. $errors = libxml_get_errors();
  25533. libxml_use_internal_errors($prev);
  25534. } catch (Throwable $t) {
  25535. throw new ManifestDocumentException($t->getMessage(), 0, $t);
  25536. }
  25537. if (count($errors) !== 0) {
  25538. throw new ManifestDocumentLoadingException($errors);
  25539. }
  25540. return new self($dom);
  25541. }
  25542. private function __construct(DOMDocument $dom)
  25543. {
  25544. $this->ensureCorrectDocumentType($dom);
  25545. $this->dom = $dom;
  25546. }
  25547. public function getContainsElement(): ContainsElement
  25548. {
  25549. return new ContainsElement($this->fetchElementByName('contains'));
  25550. }
  25551. public function getCopyrightElement(): CopyrightElement
  25552. {
  25553. return new CopyrightElement($this->fetchElementByName('copyright'));
  25554. }
  25555. public function getRequiresElement(): RequiresElement
  25556. {
  25557. return new RequiresElement($this->fetchElementByName('requires'));
  25558. }
  25559. public function hasBundlesElement(): bool
  25560. {
  25561. return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;
  25562. }
  25563. public function getBundlesElement(): BundlesElement
  25564. {
  25565. return new BundlesElement($this->fetchElementByName('bundles'));
  25566. }
  25567. private function ensureCorrectDocumentType(DOMDocument $dom): void
  25568. {
  25569. $root = $dom->documentElement;
  25570. if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {
  25571. throw new ManifestDocumentException('Not a phar.io manifest document');
  25572. }
  25573. }
  25574. private function fetchElementByName(string $elementName): DOMElement
  25575. {
  25576. $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
  25577. if (!$element instanceof DOMElement) {
  25578. throw new ManifestDocumentException(sprintf('Element %s missing', $elementName));
  25579. }
  25580. return $element;
  25581. }
  25582. }
  25583. <?php
  25584. declare (strict_types=1);
  25585. /*
  25586. * This file is part of PharIo\Manifest.
  25587. *
  25588. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25589. *
  25590. * For the full copyright and license information, please view the LICENSE
  25591. * file that was distributed with this source code.
  25592. *
  25593. */
  25594. namespace PHPUnitPHAR\PharIo\Manifest;
  25595. use DOMElement;
  25596. use DOMNodeList;
  25597. use function sprintf;
  25598. class ManifestElement
  25599. {
  25600. public const XMLNS = 'https://phar.io/xml/manifest/1.0';
  25601. /** @var DOMElement */
  25602. private $element;
  25603. public function __construct(DOMElement $element)
  25604. {
  25605. $this->element = $element;
  25606. }
  25607. protected function getAttributeValue(string $name): string
  25608. {
  25609. if (!$this->element->hasAttribute($name)) {
  25610. throw new ManifestElementException(sprintf('Attribute %s not set on element %s', $name, $this->element->localName));
  25611. }
  25612. return $this->element->getAttribute($name);
  25613. }
  25614. protected function hasAttribute(string $name): bool
  25615. {
  25616. return $this->element->hasAttribute($name);
  25617. }
  25618. protected function getChildByName(string $elementName): DOMElement
  25619. {
  25620. $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
  25621. if (!$element instanceof DOMElement) {
  25622. throw new ManifestElementException(sprintf('Element %s missing', $elementName));
  25623. }
  25624. return $element;
  25625. }
  25626. protected function getChildrenByName(string $elementName): DOMNodeList
  25627. {
  25628. $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName);
  25629. if ($elementList->length === 0) {
  25630. throw new ManifestElementException(sprintf('Element(s) %s missing', $elementName));
  25631. }
  25632. return $elementList;
  25633. }
  25634. protected function hasChild(string $elementName): bool
  25635. {
  25636. return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0;
  25637. }
  25638. }
  25639. <?php
  25640. declare (strict_types=1);
  25641. /*
  25642. * This file is part of PharIo\Manifest.
  25643. *
  25644. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25645. *
  25646. * For the full copyright and license information, please view the LICENSE
  25647. * file that was distributed with this source code.
  25648. *
  25649. */
  25650. namespace PHPUnitPHAR\PharIo\Manifest;
  25651. class PhpElement extends ManifestElement
  25652. {
  25653. public function getVersion(): string
  25654. {
  25655. return $this->getAttributeValue('version');
  25656. }
  25657. public function hasExtElements(): bool
  25658. {
  25659. return $this->hasChild('ext');
  25660. }
  25661. public function getExtElements(): ExtElementCollection
  25662. {
  25663. return new ExtElementCollection($this->getChildrenByName('ext'));
  25664. }
  25665. }
  25666. <?php
  25667. declare (strict_types=1);
  25668. /*
  25669. * This file is part of PharIo\Manifest.
  25670. *
  25671. * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
  25672. *
  25673. * For the full copyright and license information, please view the LICENSE
  25674. * file that was distributed with this source code.
  25675. *
  25676. */
  25677. namespace PHPUnitPHAR\PharIo\Manifest;
  25678. class RequiresElement extends ManifestElement
  25679. {
  25680. public function getPHPElement(): PhpElement
  25681. {
  25682. return new PhpElement($this->getChildByName('php'));
  25683. }
  25684. }
  25685. <?php
  25686. declare (strict_types=1);
  25687. /*
  25688. * This file is part of PharIo\Version.
  25689. *
  25690. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  25691. *
  25692. * For the full copyright and license information, please view the LICENSE
  25693. * file that was distributed with this source code.
  25694. */
  25695. namespace PHPUnitPHAR\PharIo\Version;
  25696. class BuildMetaData
  25697. {
  25698. /** @var string */
  25699. private $value;
  25700. public function __construct(string $value)
  25701. {
  25702. $this->value = $value;
  25703. }
  25704. public function asString(): string
  25705. {
  25706. return $this->value;
  25707. }
  25708. public function equals(BuildMetaData $other): bool
  25709. {
  25710. return $this->asString() === $other->asString();
  25711. }
  25712. }
  25713. Copyright (c) 2016-2017 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de> and contributors
  25714. All rights reserved.
  25715. Redistribution and use in source and binary forms, with or without modification,
  25716. are permitted provided that the following conditions are met:
  25717. * Redistributions of source code must retain the above copyright notice,
  25718. this list of conditions and the following disclaimer.
  25719. * Redistributions in binary form must reproduce the above copyright notice,
  25720. this list of conditions and the following disclaimer in the documentation
  25721. and/or other materials provided with the distribution.
  25722. * Neither the name of the copyright holder nor the names of contributors
  25723. may be used to endorse or promote products derived from this software
  25724. without specific prior written permission.
  25725. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25726. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
  25727. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  25728. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
  25729. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  25730. OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25731. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25732. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25733. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25734. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25735. POSSIBILITY OF SUCH DAMAGE.
  25736. <?php
  25737. declare (strict_types=1);
  25738. namespace PHPUnitPHAR\PharIo\Version;
  25739. class PreReleaseSuffix
  25740. {
  25741. private const valueScoreMap = ['dev' => 0, 'a' => 1, 'alpha' => 1, 'b' => 2, 'beta' => 2, 'rc' => 3, 'p' => 4, 'pl' => 4, 'patch' => 4];
  25742. /** @var string */
  25743. private $value;
  25744. /** @var int */
  25745. private $valueScore;
  25746. /** @var int */
  25747. private $number = 0;
  25748. /** @var string */
  25749. private $full;
  25750. /**
  25751. * @throws InvalidPreReleaseSuffixException
  25752. */
  25753. public function __construct(string $value)
  25754. {
  25755. $this->parseValue($value);
  25756. }
  25757. public function asString(): string
  25758. {
  25759. return $this->full;
  25760. }
  25761. public function getValue(): string
  25762. {
  25763. return $this->value;
  25764. }
  25765. public function getNumber(): ?int
  25766. {
  25767. return $this->number;
  25768. }
  25769. public function isGreaterThan(PreReleaseSuffix $suffix): bool
  25770. {
  25771. if ($this->valueScore > $suffix->valueScore) {
  25772. return \true;
  25773. }
  25774. if ($this->valueScore < $suffix->valueScore) {
  25775. return \false;
  25776. }
  25777. return $this->getNumber() > $suffix->getNumber();
  25778. }
  25779. private function mapValueToScore(string $value): int
  25780. {
  25781. $value = \strtolower($value);
  25782. return self::valueScoreMap[$value];
  25783. }
  25784. private function parseValue(string $value): void
  25785. {
  25786. $regex = '/-?((dev|beta|b|rc|alpha|a|patch|p|pl)\.?(\d*)).*$/i';
  25787. if (\preg_match($regex, $value, $matches) !== 1) {
  25788. throw new InvalidPreReleaseSuffixException(\sprintf('Invalid label %s', $value));
  25789. }
  25790. $this->full = $matches[1];
  25791. $this->value = $matches[2];
  25792. if ($matches[3] !== '') {
  25793. $this->number = (int) $matches[3];
  25794. }
  25795. $this->valueScore = $this->mapValueToScore($matches[2]);
  25796. }
  25797. }
  25798. <?php
  25799. declare (strict_types=1);
  25800. /*
  25801. * This file is part of PharIo\Version.
  25802. *
  25803. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  25804. *
  25805. * For the full copyright and license information, please view the LICENSE
  25806. * file that was distributed with this source code.
  25807. */
  25808. namespace PHPUnitPHAR\PharIo\Version;
  25809. class Version
  25810. {
  25811. /** @var string */
  25812. private $originalVersionString;
  25813. /** @var VersionNumber */
  25814. private $major;
  25815. /** @var VersionNumber */
  25816. private $minor;
  25817. /** @var VersionNumber */
  25818. private $patch;
  25819. /** @var null|PreReleaseSuffix */
  25820. private $preReleaseSuffix;
  25821. /** @var null|BuildMetaData */
  25822. private $buildMetadata;
  25823. public function __construct(string $versionString)
  25824. {
  25825. $this->ensureVersionStringIsValid($versionString);
  25826. $this->originalVersionString = $versionString;
  25827. }
  25828. /**
  25829. * @throws NoPreReleaseSuffixException
  25830. */
  25831. public function getPreReleaseSuffix(): PreReleaseSuffix
  25832. {
  25833. if ($this->preReleaseSuffix === null) {
  25834. throw new NoPreReleaseSuffixException('No pre-release suffix set');
  25835. }
  25836. return $this->preReleaseSuffix;
  25837. }
  25838. public function getOriginalString(): string
  25839. {
  25840. return $this->originalVersionString;
  25841. }
  25842. public function getVersionString(): string
  25843. {
  25844. $str = \sprintf('%d.%d.%d', $this->getMajor()->getValue() ?? 0, $this->getMinor()->getValue() ?? 0, $this->getPatch()->getValue() ?? 0);
  25845. if (!$this->hasPreReleaseSuffix()) {
  25846. return $str;
  25847. }
  25848. return $str . '-' . $this->getPreReleaseSuffix()->asString();
  25849. }
  25850. public function hasPreReleaseSuffix(): bool
  25851. {
  25852. return $this->preReleaseSuffix !== null;
  25853. }
  25854. public function equals(Version $other): bool
  25855. {
  25856. if ($this->getVersionString() !== $other->getVersionString()) {
  25857. return \false;
  25858. }
  25859. if ($this->hasBuildMetaData() !== $other->hasBuildMetaData()) {
  25860. return \false;
  25861. }
  25862. if ($this->hasBuildMetaData() && $other->hasBuildMetaData() && !$this->getBuildMetaData()->equals($other->getBuildMetaData())) {
  25863. return \false;
  25864. }
  25865. return \true;
  25866. }
  25867. public function isGreaterThan(Version $version): bool
  25868. {
  25869. if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) {
  25870. return \false;
  25871. }
  25872. if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) {
  25873. return \true;
  25874. }
  25875. if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) {
  25876. return \false;
  25877. }
  25878. if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) {
  25879. return \true;
  25880. }
  25881. if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) {
  25882. return \false;
  25883. }
  25884. if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) {
  25885. return \true;
  25886. }
  25887. if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
  25888. return \false;
  25889. }
  25890. if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
  25891. return \true;
  25892. }
  25893. if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) {
  25894. return \false;
  25895. }
  25896. return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix());
  25897. }
  25898. public function getMajor(): VersionNumber
  25899. {
  25900. return $this->major;
  25901. }
  25902. public function getMinor(): VersionNumber
  25903. {
  25904. return $this->minor;
  25905. }
  25906. public function getPatch(): VersionNumber
  25907. {
  25908. return $this->patch;
  25909. }
  25910. /**
  25911. * @psalm-assert-if-true BuildMetaData $this->buildMetadata
  25912. * @psalm-assert-if-true BuildMetaData $this->getBuildMetaData()
  25913. */
  25914. public function hasBuildMetaData(): bool
  25915. {
  25916. return $this->buildMetadata !== null;
  25917. }
  25918. /**
  25919. * @throws NoBuildMetaDataException
  25920. */
  25921. public function getBuildMetaData(): BuildMetaData
  25922. {
  25923. if (!$this->hasBuildMetaData()) {
  25924. throw new NoBuildMetaDataException('No build metadata set');
  25925. }
  25926. return $this->buildMetadata;
  25927. }
  25928. /**
  25929. * @param string[] $matches
  25930. *
  25931. * @throws InvalidPreReleaseSuffixException
  25932. */
  25933. private function parseVersion(array $matches): void
  25934. {
  25935. $this->major = new VersionNumber((int) $matches['Major']);
  25936. $this->minor = new VersionNumber((int) $matches['Minor']);
  25937. $this->patch = isset($matches['Patch']) ? new VersionNumber((int) $matches['Patch']) : new VersionNumber(0);
  25938. if (isset($matches['PreReleaseSuffix']) && $matches['PreReleaseSuffix'] !== '') {
  25939. $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']);
  25940. }
  25941. if (isset($matches['BuildMetadata'])) {
  25942. $this->buildMetadata = new BuildMetaData($matches['BuildMetadata']);
  25943. }
  25944. }
  25945. /**
  25946. * @param string $version
  25947. *
  25948. * @throws InvalidVersionException
  25949. */
  25950. private function ensureVersionStringIsValid($version): void
  25951. {
  25952. $regex = '/^v?
  25953. (?P<Major>0|[1-9]\d*)
  25954. \.
  25955. (?P<Minor>0|[1-9]\d*)
  25956. (\.
  25957. (?P<Patch>0|[1-9]\d*)
  25958. )?
  25959. (?:
  25960. -
  25961. (?<PreReleaseSuffix>(?:(dev|beta|b|rc|alpha|a|patch|p|pl)\.?\d*))
  25962. )?
  25963. (?:
  25964. \+
  25965. (?P<BuildMetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-@]+)*)
  25966. )?
  25967. $/xi';
  25968. if (\preg_match($regex, $version, $matches) !== 1) {
  25969. throw new InvalidVersionException(\sprintf("Version string '%s' does not follow SemVer semantics", $version));
  25970. }
  25971. $this->parseVersion($matches);
  25972. }
  25973. }
  25974. <?php
  25975. declare (strict_types=1);
  25976. /*
  25977. * This file is part of PharIo\Version.
  25978. *
  25979. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  25980. *
  25981. * For the full copyright and license information, please view the LICENSE
  25982. * file that was distributed with this source code.
  25983. */
  25984. namespace PHPUnitPHAR\PharIo\Version;
  25985. class VersionConstraintParser
  25986. {
  25987. /**
  25988. * @throws UnsupportedVersionConstraintException
  25989. */
  25990. public function parse(string $value): VersionConstraint
  25991. {
  25992. if (\strpos($value, '|') !== \false) {
  25993. return $this->handleOrGroup($value);
  25994. }
  25995. if (!\preg_match('/^[\^~*]?v?[\d.*]+(?:-.*)?$/i', $value)) {
  25996. throw new UnsupportedVersionConstraintException(\sprintf('Version constraint %s is not supported.', $value));
  25997. }
  25998. switch ($value[0]) {
  25999. case '~':
  26000. return $this->handleTildeOperator($value);
  26001. case '^':
  26002. return $this->handleCaretOperator($value);
  26003. }
  26004. $constraint = new VersionConstraintValue($value);
  26005. if ($constraint->getMajor()->isAny()) {
  26006. return new AnyVersionConstraint();
  26007. }
  26008. if ($constraint->getMinor()->isAny()) {
  26009. return new SpecificMajorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0);
  26010. }
  26011. if ($constraint->getPatch()->isAny()) {
  26012. return new SpecificMajorAndMinorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0, $constraint->getMinor()->getValue() ?? 0);
  26013. }
  26014. return new ExactVersionConstraint($constraint->getVersionString());
  26015. }
  26016. private function handleOrGroup(string $value): OrVersionConstraintGroup
  26017. {
  26018. $constraints = [];
  26019. foreach (\preg_split('{\s*\|\|?\s*}', \trim($value)) as $groupSegment) {
  26020. $constraints[] = $this->parse(\trim($groupSegment));
  26021. }
  26022. return new OrVersionConstraintGroup($value, $constraints);
  26023. }
  26024. private function handleTildeOperator(string $value): AndVersionConstraintGroup
  26025. {
  26026. $constraintValue = new VersionConstraintValue(\substr($value, 1));
  26027. if ($constraintValue->getPatch()->isAny()) {
  26028. return $this->handleCaretOperator($value);
  26029. }
  26030. $constraints = [new GreaterThanOrEqualToVersionConstraint($value, new Version(\substr($value, 1))), new SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0)];
  26031. return new AndVersionConstraintGroup($value, $constraints);
  26032. }
  26033. private function handleCaretOperator(string $value): AndVersionConstraintGroup
  26034. {
  26035. $constraintValue = new VersionConstraintValue(\substr($value, 1));
  26036. $constraints = [new GreaterThanOrEqualToVersionConstraint($value, new Version(\substr($value, 1)))];
  26037. if ($constraintValue->getMajor()->getValue() === 0) {
  26038. $constraints[] = new SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0);
  26039. } else {
  26040. $constraints[] = new SpecificMajorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0);
  26041. }
  26042. return new AndVersionConstraintGroup($value, $constraints);
  26043. }
  26044. }
  26045. <?php
  26046. declare (strict_types=1);
  26047. namespace PHPUnitPHAR\PharIo\Version;
  26048. class VersionConstraintValue
  26049. {
  26050. /** @var VersionNumber */
  26051. private $major;
  26052. /** @var VersionNumber */
  26053. private $minor;
  26054. /** @var VersionNumber */
  26055. private $patch;
  26056. /** @var string */
  26057. private $label = '';
  26058. /** @var string */
  26059. private $buildMetaData = '';
  26060. /** @var string */
  26061. private $versionString = '';
  26062. public function __construct(string $versionString)
  26063. {
  26064. $this->versionString = $versionString;
  26065. $this->parseVersion($versionString);
  26066. }
  26067. public function getLabel(): string
  26068. {
  26069. return $this->label;
  26070. }
  26071. public function getBuildMetaData(): string
  26072. {
  26073. return $this->buildMetaData;
  26074. }
  26075. public function getVersionString(): string
  26076. {
  26077. return $this->versionString;
  26078. }
  26079. public function getMajor(): VersionNumber
  26080. {
  26081. return $this->major;
  26082. }
  26083. public function getMinor(): VersionNumber
  26084. {
  26085. return $this->minor;
  26086. }
  26087. public function getPatch(): VersionNumber
  26088. {
  26089. return $this->patch;
  26090. }
  26091. private function parseVersion(string $versionString): void
  26092. {
  26093. $this->extractBuildMetaData($versionString);
  26094. $this->extractLabel($versionString);
  26095. $this->stripPotentialVPrefix($versionString);
  26096. $versionSegments = \explode('.', $versionString);
  26097. $this->major = new VersionNumber(\is_numeric($versionSegments[0]) ? (int) $versionSegments[0] : null);
  26098. $minorValue = isset($versionSegments[1]) && \is_numeric($versionSegments[1]) ? (int) $versionSegments[1] : null;
  26099. $patchValue = isset($versionSegments[2]) && \is_numeric($versionSegments[2]) ? (int) $versionSegments[2] : null;
  26100. $this->minor = new VersionNumber($minorValue);
  26101. $this->patch = new VersionNumber($patchValue);
  26102. }
  26103. private function extractBuildMetaData(string &$versionString): void
  26104. {
  26105. if (\preg_match('/\+(.*)/', $versionString, $matches) === 1) {
  26106. $this->buildMetaData = $matches[1];
  26107. $versionString = \str_replace($matches[0], '', $versionString);
  26108. }
  26109. }
  26110. private function extractLabel(string &$versionString): void
  26111. {
  26112. if (\preg_match('/-(.*)/', $versionString, $matches) === 1) {
  26113. $this->label = $matches[1];
  26114. $versionString = \str_replace($matches[0], '', $versionString);
  26115. }
  26116. }
  26117. private function stripPotentialVPrefix(string &$versionString): void
  26118. {
  26119. if ($versionString[0] !== 'v') {
  26120. return;
  26121. }
  26122. $versionString = \substr($versionString, 1);
  26123. }
  26124. }
  26125. <?php
  26126. declare (strict_types=1);
  26127. /*
  26128. * This file is part of PharIo\Version.
  26129. *
  26130. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26131. *
  26132. * For the full copyright and license information, please view the LICENSE
  26133. * file that was distributed with this source code.
  26134. */
  26135. namespace PHPUnitPHAR\PharIo\Version;
  26136. class VersionNumber
  26137. {
  26138. /** @var ?int */
  26139. private $value;
  26140. public function __construct(?int $value)
  26141. {
  26142. $this->value = $value;
  26143. }
  26144. public function isAny(): bool
  26145. {
  26146. return $this->value === null;
  26147. }
  26148. public function getValue(): ?int
  26149. {
  26150. return $this->value;
  26151. }
  26152. }
  26153. <?php
  26154. declare (strict_types=1);
  26155. /*
  26156. * This file is part of PharIo\Version.
  26157. *
  26158. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26159. *
  26160. * For the full copyright and license information, please view the LICENSE
  26161. * file that was distributed with this source code.
  26162. */
  26163. namespace PHPUnitPHAR\PharIo\Version;
  26164. abstract class AbstractVersionConstraint implements VersionConstraint
  26165. {
  26166. /** @var string */
  26167. private $originalValue;
  26168. public function __construct(string $originalValue)
  26169. {
  26170. $this->originalValue = $originalValue;
  26171. }
  26172. public function asString(): string
  26173. {
  26174. return $this->originalValue;
  26175. }
  26176. }
  26177. <?php
  26178. declare (strict_types=1);
  26179. /*
  26180. * This file is part of PharIo\Version.
  26181. *
  26182. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26183. *
  26184. * For the full copyright and license information, please view the LICENSE
  26185. * file that was distributed with this source code.
  26186. */
  26187. namespace PHPUnitPHAR\PharIo\Version;
  26188. class AndVersionConstraintGroup extends AbstractVersionConstraint
  26189. {
  26190. /** @var VersionConstraint[] */
  26191. private $constraints = [];
  26192. /**
  26193. * @param VersionConstraint[] $constraints
  26194. */
  26195. public function __construct(string $originalValue, array $constraints)
  26196. {
  26197. parent::__construct($originalValue);
  26198. $this->constraints = $constraints;
  26199. }
  26200. public function complies(Version $version): bool
  26201. {
  26202. foreach ($this->constraints as $constraint) {
  26203. if (!$constraint->complies($version)) {
  26204. return \false;
  26205. }
  26206. }
  26207. return \true;
  26208. }
  26209. }
  26210. <?php
  26211. declare (strict_types=1);
  26212. /*
  26213. * This file is part of PharIo\Version.
  26214. *
  26215. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26216. *
  26217. * For the full copyright and license information, please view the LICENSE
  26218. * file that was distributed with this source code.
  26219. */
  26220. namespace PHPUnitPHAR\PharIo\Version;
  26221. class AnyVersionConstraint implements VersionConstraint
  26222. {
  26223. public function complies(Version $version): bool
  26224. {
  26225. return \true;
  26226. }
  26227. public function asString(): string
  26228. {
  26229. return '*';
  26230. }
  26231. }
  26232. <?php
  26233. declare (strict_types=1);
  26234. /*
  26235. * This file is part of PharIo\Version.
  26236. *
  26237. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26238. *
  26239. * For the full copyright and license information, please view the LICENSE
  26240. * file that was distributed with this source code.
  26241. */
  26242. namespace PHPUnitPHAR\PharIo\Version;
  26243. class ExactVersionConstraint extends AbstractVersionConstraint
  26244. {
  26245. public function complies(Version $version): bool
  26246. {
  26247. $other = $version->getVersionString();
  26248. if ($version->hasBuildMetaData()) {
  26249. $other .= '+' . $version->getBuildMetaData()->asString();
  26250. }
  26251. return $this->asString() === $other;
  26252. }
  26253. }
  26254. <?php
  26255. declare (strict_types=1);
  26256. /*
  26257. * This file is part of PharIo\Version.
  26258. *
  26259. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26260. *
  26261. * For the full copyright and license information, please view the LICENSE
  26262. * file that was distributed with this source code.
  26263. */
  26264. namespace PHPUnitPHAR\PharIo\Version;
  26265. class GreaterThanOrEqualToVersionConstraint extends AbstractVersionConstraint
  26266. {
  26267. /** @var Version */
  26268. private $minimalVersion;
  26269. public function __construct(string $originalValue, Version $minimalVersion)
  26270. {
  26271. parent::__construct($originalValue);
  26272. $this->minimalVersion = $minimalVersion;
  26273. }
  26274. public function complies(Version $version): bool
  26275. {
  26276. return $version->getVersionString() === $this->minimalVersion->getVersionString() || $version->isGreaterThan($this->minimalVersion);
  26277. }
  26278. }
  26279. <?php
  26280. declare (strict_types=1);
  26281. /*
  26282. * This file is part of PharIo\Version.
  26283. *
  26284. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26285. *
  26286. * For the full copyright and license information, please view the LICENSE
  26287. * file that was distributed with this source code.
  26288. */
  26289. namespace PHPUnitPHAR\PharIo\Version;
  26290. class OrVersionConstraintGroup extends AbstractVersionConstraint
  26291. {
  26292. /** @var VersionConstraint[] */
  26293. private $constraints = [];
  26294. /**
  26295. * @param string $originalValue
  26296. * @param VersionConstraint[] $constraints
  26297. */
  26298. public function __construct($originalValue, array $constraints)
  26299. {
  26300. parent::__construct($originalValue);
  26301. $this->constraints = $constraints;
  26302. }
  26303. public function complies(Version $version): bool
  26304. {
  26305. foreach ($this->constraints as $constraint) {
  26306. if ($constraint->complies($version)) {
  26307. return \true;
  26308. }
  26309. }
  26310. return \false;
  26311. }
  26312. }
  26313. <?php
  26314. declare (strict_types=1);
  26315. /*
  26316. * This file is part of PharIo\Version.
  26317. *
  26318. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26319. *
  26320. * For the full copyright and license information, please view the LICENSE
  26321. * file that was distributed with this source code.
  26322. */
  26323. namespace PHPUnitPHAR\PharIo\Version;
  26324. class SpecificMajorAndMinorVersionConstraint extends AbstractVersionConstraint
  26325. {
  26326. /** @var int */
  26327. private $major;
  26328. /** @var int */
  26329. private $minor;
  26330. public function __construct(string $originalValue, int $major, int $minor)
  26331. {
  26332. parent::__construct($originalValue);
  26333. $this->major = $major;
  26334. $this->minor = $minor;
  26335. }
  26336. public function complies(Version $version): bool
  26337. {
  26338. if ($version->getMajor()->getValue() !== $this->major) {
  26339. return \false;
  26340. }
  26341. return $version->getMinor()->getValue() === $this->minor;
  26342. }
  26343. }
  26344. <?php
  26345. declare (strict_types=1);
  26346. /*
  26347. * This file is part of PharIo\Version.
  26348. *
  26349. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26350. *
  26351. * For the full copyright and license information, please view the LICENSE
  26352. * file that was distributed with this source code.
  26353. */
  26354. namespace PHPUnitPHAR\PharIo\Version;
  26355. class SpecificMajorVersionConstraint extends AbstractVersionConstraint
  26356. {
  26357. /** @var int */
  26358. private $major;
  26359. public function __construct(string $originalValue, int $major)
  26360. {
  26361. parent::__construct($originalValue);
  26362. $this->major = $major;
  26363. }
  26364. public function complies(Version $version): bool
  26365. {
  26366. return $version->getMajor()->getValue() === $this->major;
  26367. }
  26368. }
  26369. <?php
  26370. declare (strict_types=1);
  26371. /*
  26372. * This file is part of PharIo\Version.
  26373. *
  26374. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26375. *
  26376. * For the full copyright and license information, please view the LICENSE
  26377. * file that was distributed with this source code.
  26378. */
  26379. namespace PHPUnitPHAR\PharIo\Version;
  26380. interface VersionConstraint
  26381. {
  26382. public function complies(Version $version): bool;
  26383. public function asString(): string;
  26384. }
  26385. <?php
  26386. declare (strict_types=1);
  26387. /*
  26388. * This file is part of PharIo\Version.
  26389. *
  26390. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26391. *
  26392. * For the full copyright and license information, please view the LICENSE
  26393. * file that was distributed with this source code.
  26394. */
  26395. namespace PHPUnitPHAR\PharIo\Version;
  26396. use Throwable;
  26397. interface Exception extends Throwable
  26398. {
  26399. }
  26400. <?php
  26401. declare (strict_types=1);
  26402. namespace PHPUnitPHAR\PharIo\Version;
  26403. class InvalidPreReleaseSuffixException extends \Exception implements Exception
  26404. {
  26405. }
  26406. <?php
  26407. declare (strict_types=1);
  26408. namespace PHPUnitPHAR\PharIo\Version;
  26409. class InvalidVersionException extends \InvalidArgumentException implements Exception
  26410. {
  26411. }
  26412. <?php
  26413. declare (strict_types=1);
  26414. namespace PHPUnitPHAR\PharIo\Version;
  26415. class NoBuildMetaDataException extends \Exception implements Exception
  26416. {
  26417. }
  26418. <?php
  26419. declare (strict_types=1);
  26420. namespace PHPUnitPHAR\PharIo\Version;
  26421. class NoPreReleaseSuffixException extends \Exception implements Exception
  26422. {
  26423. }
  26424. <?php
  26425. declare (strict_types=1);
  26426. /*
  26427. * This file is part of PharIo\Version.
  26428. *
  26429. * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
  26430. *
  26431. * For the full copyright and license information, please view the LICENSE
  26432. * file that was distributed with this source code.
  26433. */
  26434. namespace PHPUnitPHAR\PharIo\Version;
  26435. final class UnsupportedVersionConstraintException extends \RuntimeException implements Exception
  26436. {
  26437. }
  26438. <?php
  26439. declare (strict_types=1);
  26440. /*
  26441. * This file is part of phpunit/php-code-coverage.
  26442. *
  26443. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  26444. *
  26445. * For the full copyright and license information, please view the LICENSE
  26446. * file that was distributed with this source code.
  26447. */
  26448. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  26449. use function array_diff;
  26450. use function array_diff_key;
  26451. use function array_flip;
  26452. use function array_keys;
  26453. use function array_merge;
  26454. use function array_merge_recursive;
  26455. use function array_unique;
  26456. use function count;
  26457. use function explode;
  26458. use function is_array;
  26459. use function is_file;
  26460. use function sort;
  26461. use ReflectionClass;
  26462. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData;
  26463. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
  26464. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
  26465. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Builder;
  26466. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory;
  26467. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\CachingFileAnalyser;
  26468. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
  26469. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
  26470. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
  26471. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
  26472. use PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup\Wizard;
  26473. /**
  26474. * Provides collection functionality for PHP code coverage information.
  26475. *
  26476. * @psalm-type TestType = array{
  26477. * size: string,
  26478. * status: string,
  26479. * }
  26480. */
  26481. final class CodeCoverage
  26482. {
  26483. private const UNCOVERED_FILES = 'UNCOVERED_FILES';
  26484. private readonly Driver $driver;
  26485. private readonly Filter $filter;
  26486. private readonly Wizard $wizard;
  26487. private bool $checkForUnintentionallyCoveredCode = \false;
  26488. private bool $includeUncoveredFiles = \true;
  26489. private bool $ignoreDeprecatedCode = \false;
  26490. private ?string $currentId = null;
  26491. private ?TestSize $currentSize = null;
  26492. private ProcessedCodeCoverageData $data;
  26493. private bool $useAnnotationsForIgnoringCode = \true;
  26494. /**
  26495. * @psalm-var array<string,list<int>>
  26496. */
  26497. private array $linesToBeIgnored = [];
  26498. /**
  26499. * @psalm-var array<string, TestType>
  26500. */
  26501. private array $tests = [];
  26502. /**
  26503. * @psalm-var list<class-string>
  26504. */
  26505. private array $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
  26506. private ?FileAnalyser $analyser = null;
  26507. private ?string $cacheDirectory = null;
  26508. private ?Directory $cachedReport = null;
  26509. public function __construct(Driver $driver, Filter $filter)
  26510. {
  26511. $this->driver = $driver;
  26512. $this->filter = $filter;
  26513. $this->data = new ProcessedCodeCoverageData();
  26514. $this->wizard = new Wizard();
  26515. }
  26516. /**
  26517. * Returns the code coverage information as a graph of node objects.
  26518. */
  26519. public function getReport(): Directory
  26520. {
  26521. if ($this->cachedReport === null) {
  26522. $this->cachedReport = (new Builder($this->analyser()))->build($this);
  26523. }
  26524. return $this->cachedReport;
  26525. }
  26526. /**
  26527. * Clears collected code coverage data.
  26528. */
  26529. public function clear(): void
  26530. {
  26531. $this->currentId = null;
  26532. $this->currentSize = null;
  26533. $this->data = new ProcessedCodeCoverageData();
  26534. $this->tests = [];
  26535. $this->cachedReport = null;
  26536. }
  26537. /**
  26538. * @internal
  26539. */
  26540. public function clearCache(): void
  26541. {
  26542. $this->cachedReport = null;
  26543. }
  26544. /**
  26545. * Returns the filter object used.
  26546. */
  26547. public function filter(): Filter
  26548. {
  26549. return $this->filter;
  26550. }
  26551. /**
  26552. * Returns the collected code coverage data.
  26553. */
  26554. public function getData(bool $raw = \false): ProcessedCodeCoverageData
  26555. {
  26556. if (!$raw) {
  26557. if ($this->includeUncoveredFiles) {
  26558. $this->addUncoveredFilesFromFilter();
  26559. }
  26560. }
  26561. return $this->data;
  26562. }
  26563. /**
  26564. * Sets the coverage data.
  26565. */
  26566. public function setData(ProcessedCodeCoverageData $data): void
  26567. {
  26568. $this->data = $data;
  26569. }
  26570. /**
  26571. * @psalm-return array<string, TestType>
  26572. */
  26573. public function getTests(): array
  26574. {
  26575. return $this->tests;
  26576. }
  26577. /**
  26578. * @psalm-param array<string, TestType> $tests
  26579. */
  26580. public function setTests(array $tests): void
  26581. {
  26582. $this->tests = $tests;
  26583. }
  26584. public function start(string $id, ?TestSize $size = null, bool $clear = \false): void
  26585. {
  26586. if ($clear) {
  26587. $this->clear();
  26588. }
  26589. $this->currentId = $id;
  26590. $this->currentSize = $size;
  26591. $this->driver->start();
  26592. $this->cachedReport = null;
  26593. }
  26594. /**
  26595. * @psalm-param array<string,list<int>> $linesToBeIgnored
  26596. */
  26597. public function stop(bool $append = \true, ?TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): RawCodeCoverageData
  26598. {
  26599. $data = $this->driver->stop();
  26600. $this->linesToBeIgnored = array_merge_recursive($this->linesToBeIgnored, $linesToBeIgnored);
  26601. $this->append($data, null, $append, $status, $linesToBeCovered, $linesToBeUsed, $linesToBeIgnored);
  26602. $this->currentId = null;
  26603. $this->currentSize = null;
  26604. $this->cachedReport = null;
  26605. return $data;
  26606. }
  26607. /**
  26608. * @psalm-param array<string,list<int>> $linesToBeIgnored
  26609. *
  26610. * @throws ReflectionException
  26611. * @throws TestIdMissingException
  26612. * @throws UnintentionallyCoveredCodeException
  26613. */
  26614. public function append(RawCodeCoverageData $rawData, ?string $id = null, bool $append = \true, ?TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): void
  26615. {
  26616. if ($id === null) {
  26617. $id = $this->currentId;
  26618. }
  26619. if ($id === null) {
  26620. throw new TestIdMissingException();
  26621. }
  26622. $this->cachedReport = null;
  26623. if ($status === null) {
  26624. $status = TestStatus::unknown();
  26625. }
  26626. $size = $this->currentSize;
  26627. if ($size === null) {
  26628. $size = TestSize::unknown();
  26629. }
  26630. $this->applyFilter($rawData);
  26631. $this->applyExecutableLinesFilter($rawData);
  26632. if ($this->useAnnotationsForIgnoringCode) {
  26633. $this->applyIgnoredLinesFilter($rawData, $linesToBeIgnored);
  26634. }
  26635. $this->data->initializeUnseenData($rawData);
  26636. if (!$append) {
  26637. return;
  26638. }
  26639. if ($id === self::UNCOVERED_FILES) {
  26640. return;
  26641. }
  26642. $this->applyCoversAndUsesFilter($rawData, $linesToBeCovered, $linesToBeUsed, $size);
  26643. if (empty($rawData->lineCoverage())) {
  26644. return;
  26645. }
  26646. $this->tests[$id] = ['size' => $size->asString(), 'status' => $status->asString()];
  26647. $this->data->markCodeAsExecutedByTestCase($id, $rawData);
  26648. }
  26649. /**
  26650. * Merges the data from another instance.
  26651. */
  26652. public function merge(self $that): void
  26653. {
  26654. $this->filter->includeFiles($that->filter()->files());
  26655. $this->data->merge($that->data);
  26656. $this->tests = array_merge($this->tests, $that->getTests());
  26657. $this->cachedReport = null;
  26658. }
  26659. public function enableCheckForUnintentionallyCoveredCode(): void
  26660. {
  26661. $this->checkForUnintentionallyCoveredCode = \true;
  26662. }
  26663. public function disableCheckForUnintentionallyCoveredCode(): void
  26664. {
  26665. $this->checkForUnintentionallyCoveredCode = \false;
  26666. }
  26667. public function includeUncoveredFiles(): void
  26668. {
  26669. $this->includeUncoveredFiles = \true;
  26670. }
  26671. public function excludeUncoveredFiles(): void
  26672. {
  26673. $this->includeUncoveredFiles = \false;
  26674. }
  26675. public function enableAnnotationsForIgnoringCode(): void
  26676. {
  26677. $this->useAnnotationsForIgnoringCode = \true;
  26678. }
  26679. public function disableAnnotationsForIgnoringCode(): void
  26680. {
  26681. $this->useAnnotationsForIgnoringCode = \false;
  26682. }
  26683. public function ignoreDeprecatedCode(): void
  26684. {
  26685. $this->ignoreDeprecatedCode = \true;
  26686. }
  26687. public function doNotIgnoreDeprecatedCode(): void
  26688. {
  26689. $this->ignoreDeprecatedCode = \false;
  26690. }
  26691. /**
  26692. * @psalm-assert-if-true !null $this->cacheDirectory
  26693. */
  26694. public function cachesStaticAnalysis(): bool
  26695. {
  26696. return $this->cacheDirectory !== null;
  26697. }
  26698. public function cacheStaticAnalysis(string $directory): void
  26699. {
  26700. $this->cacheDirectory = $directory;
  26701. }
  26702. public function doNotCacheStaticAnalysis(): void
  26703. {
  26704. $this->cacheDirectory = null;
  26705. }
  26706. /**
  26707. * @throws StaticAnalysisCacheNotConfiguredException
  26708. */
  26709. public function cacheDirectory(): string
  26710. {
  26711. if (!$this->cachesStaticAnalysis()) {
  26712. throw new StaticAnalysisCacheNotConfiguredException('The static analysis cache is not configured');
  26713. }
  26714. return $this->cacheDirectory;
  26715. }
  26716. /**
  26717. * @psalm-param class-string $className
  26718. */
  26719. public function excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(string $className): void
  26720. {
  26721. $this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck[] = $className;
  26722. }
  26723. public function enableBranchAndPathCoverage(): void
  26724. {
  26725. $this->driver->enableBranchAndPathCoverage();
  26726. }
  26727. public function disableBranchAndPathCoverage(): void
  26728. {
  26729. $this->driver->disableBranchAndPathCoverage();
  26730. }
  26731. public function collectsBranchAndPathCoverage(): bool
  26732. {
  26733. return $this->driver->collectsBranchAndPathCoverage();
  26734. }
  26735. public function detectsDeadCode(): bool
  26736. {
  26737. return $this->driver->detectsDeadCode();
  26738. }
  26739. /**
  26740. * @throws ReflectionException
  26741. * @throws UnintentionallyCoveredCodeException
  26742. */
  26743. private function applyCoversAndUsesFilter(RawCodeCoverageData $rawData, array|false $linesToBeCovered, array $linesToBeUsed, TestSize $size): void
  26744. {
  26745. if ($linesToBeCovered === \false) {
  26746. $rawData->clear();
  26747. return;
  26748. }
  26749. if (empty($linesToBeCovered)) {
  26750. return;
  26751. }
  26752. if ($this->checkForUnintentionallyCoveredCode && !$size->isMedium() && !$size->isLarge()) {
  26753. $this->performUnintentionallyCoveredCodeCheck($rawData, $linesToBeCovered, $linesToBeUsed);
  26754. }
  26755. $rawLineData = $rawData->lineCoverage();
  26756. $filesWithNoCoverage = array_diff_key($rawLineData, $linesToBeCovered);
  26757. foreach (array_keys($filesWithNoCoverage) as $fileWithNoCoverage) {
  26758. $rawData->removeCoverageDataForFile($fileWithNoCoverage);
  26759. }
  26760. if (is_array($linesToBeCovered)) {
  26761. foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
  26762. $rawData->keepLineCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
  26763. $rawData->keepFunctionCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
  26764. }
  26765. }
  26766. }
  26767. private function applyFilter(RawCodeCoverageData $data): void
  26768. {
  26769. if ($this->filter->isEmpty()) {
  26770. return;
  26771. }
  26772. foreach (array_keys($data->lineCoverage()) as $filename) {
  26773. if ($this->filter->isExcluded($filename)) {
  26774. $data->removeCoverageDataForFile($filename);
  26775. }
  26776. }
  26777. }
  26778. private function applyExecutableLinesFilter(RawCodeCoverageData $data): void
  26779. {
  26780. foreach (array_keys($data->lineCoverage()) as $filename) {
  26781. if (!$this->filter->isFile($filename)) {
  26782. continue;
  26783. }
  26784. $linesToBranchMap = $this->analyser()->executableLinesIn($filename);
  26785. $data->keepLineCoverageDataOnlyForLines($filename, array_keys($linesToBranchMap));
  26786. $data->markExecutableLineByBranch($filename, $linesToBranchMap);
  26787. }
  26788. }
  26789. /**
  26790. * @psalm-param array<string,list<int>> $linesToBeIgnored
  26791. */
  26792. private function applyIgnoredLinesFilter(RawCodeCoverageData $data, array $linesToBeIgnored): void
  26793. {
  26794. foreach (array_keys($data->lineCoverage()) as $filename) {
  26795. if (!$this->filter->isFile($filename)) {
  26796. continue;
  26797. }
  26798. if (isset($linesToBeIgnored[$filename])) {
  26799. $data->removeCoverageDataForLines($filename, $linesToBeIgnored[$filename]);
  26800. }
  26801. $data->removeCoverageDataForLines($filename, $this->analyser()->ignoredLinesFor($filename));
  26802. }
  26803. }
  26804. /**
  26805. * @throws UnintentionallyCoveredCodeException
  26806. */
  26807. private function addUncoveredFilesFromFilter(): void
  26808. {
  26809. $uncoveredFiles = array_diff($this->filter->files(), $this->data->coveredFiles());
  26810. foreach ($uncoveredFiles as $uncoveredFile) {
  26811. if (is_file($uncoveredFile)) {
  26812. $this->append(RawCodeCoverageData::fromUncoveredFile($uncoveredFile, $this->analyser()), self::UNCOVERED_FILES, linesToBeIgnored: $this->linesToBeIgnored);
  26813. }
  26814. }
  26815. }
  26816. /**
  26817. * @throws ReflectionException
  26818. * @throws UnintentionallyCoveredCodeException
  26819. */
  26820. private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $data, array $linesToBeCovered, array $linesToBeUsed): void
  26821. {
  26822. $allowedLines = $this->getAllowedLines($linesToBeCovered, $linesToBeUsed);
  26823. $unintentionallyCoveredUnits = [];
  26824. foreach ($data->lineCoverage() as $file => $_data) {
  26825. foreach ($_data as $line => $flag) {
  26826. if ($flag === 1 && !isset($allowedLines[$file][$line])) {
  26827. $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
  26828. }
  26829. }
  26830. }
  26831. $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
  26832. if (!empty($unintentionallyCoveredUnits)) {
  26833. throw new UnintentionallyCoveredCodeException($unintentionallyCoveredUnits);
  26834. }
  26835. }
  26836. private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
  26837. {
  26838. $allowedLines = [];
  26839. foreach (array_keys($linesToBeCovered) as $file) {
  26840. if (!isset($allowedLines[$file])) {
  26841. $allowedLines[$file] = [];
  26842. }
  26843. $allowedLines[$file] = array_merge($allowedLines[$file], $linesToBeCovered[$file]);
  26844. }
  26845. foreach (array_keys($linesToBeUsed) as $file) {
  26846. if (!isset($allowedLines[$file])) {
  26847. $allowedLines[$file] = [];
  26848. }
  26849. $allowedLines[$file] = array_merge($allowedLines[$file], $linesToBeUsed[$file]);
  26850. }
  26851. foreach (array_keys($allowedLines) as $file) {
  26852. $allowedLines[$file] = array_flip(array_unique($allowedLines[$file]));
  26853. }
  26854. return $allowedLines;
  26855. }
  26856. /**
  26857. * @param list<string> $unintentionallyCoveredUnits
  26858. *
  26859. * @throws ReflectionException
  26860. *
  26861. * @return list<string>
  26862. */
  26863. private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
  26864. {
  26865. $unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
  26866. $processed = [];
  26867. foreach ($unintentionallyCoveredUnits as $unintentionallyCoveredUnit) {
  26868. $tmp = explode('::', $unintentionallyCoveredUnit);
  26869. if (count($tmp) !== 2) {
  26870. $processed[] = $unintentionallyCoveredUnit;
  26871. continue;
  26872. }
  26873. try {
  26874. $class = new ReflectionClass($tmp[0]);
  26875. foreach ($this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck as $parentClass) {
  26876. if ($class->isSubclassOf($parentClass)) {
  26877. continue 2;
  26878. }
  26879. }
  26880. } catch (\ReflectionException $e) {
  26881. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  26882. }
  26883. $processed[] = $tmp[0];
  26884. }
  26885. $processed = array_unique($processed);
  26886. sort($processed);
  26887. return $processed;
  26888. }
  26889. private function analyser(): FileAnalyser
  26890. {
  26891. if ($this->analyser !== null) {
  26892. return $this->analyser;
  26893. }
  26894. $this->analyser = new ParsingFileAnalyser($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
  26895. if ($this->cachesStaticAnalysis()) {
  26896. $this->analyser = new CachingFileAnalyser($this->cacheDirectory, $this->analyser, $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
  26897. }
  26898. return $this->analyser;
  26899. }
  26900. }
  26901. <?php
  26902. declare (strict_types=1);
  26903. /*
  26904. * This file is part of phpunit/php-code-coverage.
  26905. *
  26906. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  26907. *
  26908. * For the full copyright and license information, please view the LICENSE
  26909. * file that was distributed with this source code.
  26910. */
  26911. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data;
  26912. use function array_key_exists;
  26913. use function array_keys;
  26914. use function array_merge;
  26915. use function array_unique;
  26916. use function count;
  26917. use function is_array;
  26918. use function ksort;
  26919. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
  26920. /**
  26921. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  26922. *
  26923. * @psalm-import-type XdebugFunctionCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
  26924. *
  26925. * @psalm-type TestIdType = string
  26926. */
  26927. final class ProcessedCodeCoverageData
  26928. {
  26929. /**
  26930. * Line coverage data.
  26931. * An array of filenames, each having an array of linenumbers, each executable line having an array of testcase ids.
  26932. *
  26933. * @psalm-var array<string, array<int, null|list<TestIdType>>>
  26934. */
  26935. private array $lineCoverage = [];
  26936. /**
  26937. * Function coverage data.
  26938. * Maintains base format of raw data (@see https://xdebug.org/docs/code_coverage), but each 'hit' entry is an array
  26939. * of testcase ids.
  26940. *
  26941. * @psalm-var array<string, array<string, array{
  26942. * branches: array<int, array{
  26943. * op_start: int,
  26944. * op_end: int,
  26945. * line_start: int,
  26946. * line_end: int,
  26947. * hit: list<TestIdType>,
  26948. * out: array<int, int>,
  26949. * out_hit: array<int, int>,
  26950. * }>,
  26951. * paths: array<int, array{
  26952. * path: array<int, int>,
  26953. * hit: list<TestIdType>,
  26954. * }>,
  26955. * hit: list<TestIdType>
  26956. * }>>
  26957. */
  26958. private array $functionCoverage = [];
  26959. public function initializeUnseenData(RawCodeCoverageData $rawData): void
  26960. {
  26961. foreach ($rawData->lineCoverage() as $file => $lines) {
  26962. if (!isset($this->lineCoverage[$file])) {
  26963. $this->lineCoverage[$file] = [];
  26964. foreach ($lines as $k => $v) {
  26965. $this->lineCoverage[$file][$k] = $v === Driver::LINE_NOT_EXECUTABLE ? null : [];
  26966. }
  26967. }
  26968. }
  26969. foreach ($rawData->functionCoverage() as $file => $functions) {
  26970. foreach ($functions as $functionName => $functionData) {
  26971. if (isset($this->functionCoverage[$file][$functionName])) {
  26972. $this->initPreviouslySeenFunction($file, $functionName, $functionData);
  26973. } else {
  26974. $this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
  26975. }
  26976. }
  26977. }
  26978. }
  26979. public function markCodeAsExecutedByTestCase(string $testCaseId, RawCodeCoverageData $executedCode): void
  26980. {
  26981. foreach ($executedCode->lineCoverage() as $file => $lines) {
  26982. foreach ($lines as $k => $v) {
  26983. if ($v === Driver::LINE_EXECUTED) {
  26984. $this->lineCoverage[$file][$k][] = $testCaseId;
  26985. }
  26986. }
  26987. }
  26988. foreach ($executedCode->functionCoverage() as $file => $functions) {
  26989. foreach ($functions as $functionName => $functionData) {
  26990. foreach ($functionData['branches'] as $branchId => $branchData) {
  26991. if ($branchData['hit'] === Driver::BRANCH_HIT) {
  26992. $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'][] = $testCaseId;
  26993. }
  26994. }
  26995. foreach ($functionData['paths'] as $pathId => $pathData) {
  26996. if ($pathData['hit'] === Driver::BRANCH_HIT) {
  26997. $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'][] = $testCaseId;
  26998. }
  26999. }
  27000. }
  27001. }
  27002. }
  27003. public function setLineCoverage(array $lineCoverage): void
  27004. {
  27005. $this->lineCoverage = $lineCoverage;
  27006. }
  27007. public function lineCoverage(): array
  27008. {
  27009. ksort($this->lineCoverage);
  27010. return $this->lineCoverage;
  27011. }
  27012. public function setFunctionCoverage(array $functionCoverage): void
  27013. {
  27014. $this->functionCoverage = $functionCoverage;
  27015. }
  27016. public function functionCoverage(): array
  27017. {
  27018. ksort($this->functionCoverage);
  27019. return $this->functionCoverage;
  27020. }
  27021. public function coveredFiles(): array
  27022. {
  27023. ksort($this->lineCoverage);
  27024. return array_keys($this->lineCoverage);
  27025. }
  27026. public function renameFile(string $oldFile, string $newFile): void
  27027. {
  27028. $this->lineCoverage[$newFile] = $this->lineCoverage[$oldFile];
  27029. if (isset($this->functionCoverage[$oldFile])) {
  27030. $this->functionCoverage[$newFile] = $this->functionCoverage[$oldFile];
  27031. }
  27032. unset($this->lineCoverage[$oldFile], $this->functionCoverage[$oldFile]);
  27033. }
  27034. public function merge(self $newData): void
  27035. {
  27036. foreach ($newData->lineCoverage as $file => $lines) {
  27037. if (!isset($this->lineCoverage[$file])) {
  27038. $this->lineCoverage[$file] = $lines;
  27039. continue;
  27040. }
  27041. // we should compare the lines if any of two contains data
  27042. $compareLineNumbers = array_unique(array_merge(array_keys($this->lineCoverage[$file]), array_keys($newData->lineCoverage[$file])));
  27043. foreach ($compareLineNumbers as $line) {
  27044. $thatPriority = $this->priorityForLine($newData->lineCoverage[$file], $line);
  27045. $thisPriority = $this->priorityForLine($this->lineCoverage[$file], $line);
  27046. if ($thatPriority > $thisPriority) {
  27047. $this->lineCoverage[$file][$line] = $newData->lineCoverage[$file][$line];
  27048. } elseif ($thatPriority === $thisPriority && is_array($this->lineCoverage[$file][$line])) {
  27049. $this->lineCoverage[$file][$line] = array_unique(array_merge($this->lineCoverage[$file][$line], $newData->lineCoverage[$file][$line]));
  27050. }
  27051. }
  27052. }
  27053. foreach ($newData->functionCoverage as $file => $functions) {
  27054. if (!isset($this->functionCoverage[$file])) {
  27055. $this->functionCoverage[$file] = $functions;
  27056. continue;
  27057. }
  27058. foreach ($functions as $functionName => $functionData) {
  27059. if (isset($this->functionCoverage[$file][$functionName])) {
  27060. $this->initPreviouslySeenFunction($file, $functionName, $functionData);
  27061. } else {
  27062. $this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
  27063. }
  27064. foreach ($functionData['branches'] as $branchId => $branchData) {
  27065. $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'], $branchData['hit']));
  27066. }
  27067. foreach ($functionData['paths'] as $pathId => $pathData) {
  27068. $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'], $pathData['hit']));
  27069. }
  27070. }
  27071. }
  27072. }
  27073. /**
  27074. * Determine the priority for a line.
  27075. *
  27076. * 1 = the line is not set
  27077. * 2 = the line has not been tested
  27078. * 3 = the line is dead code
  27079. * 4 = the line has been tested
  27080. *
  27081. * During a merge, a higher number is better.
  27082. */
  27083. private function priorityForLine(array $data, int $line): int
  27084. {
  27085. if (!array_key_exists($line, $data)) {
  27086. return 1;
  27087. }
  27088. if (is_array($data[$line]) && count($data[$line]) === 0) {
  27089. return 2;
  27090. }
  27091. if ($data[$line] === null) {
  27092. return 3;
  27093. }
  27094. return 4;
  27095. }
  27096. /**
  27097. * For a function we have never seen before, copy all data over and simply init the 'hit' array.
  27098. *
  27099. * @psalm-param XdebugFunctionCoverageType $functionData
  27100. */
  27101. private function initPreviouslyUnseenFunction(string $file, string $functionName, array $functionData): void
  27102. {
  27103. $this->functionCoverage[$file][$functionName] = $functionData;
  27104. foreach (array_keys($functionData['branches']) as $branchId) {
  27105. $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
  27106. }
  27107. foreach (array_keys($functionData['paths']) as $pathId) {
  27108. $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
  27109. }
  27110. }
  27111. /**
  27112. * For a function we have seen before, only copy over and init the 'hit' array for any unseen branches and paths.
  27113. * Techniques such as mocking and where the contents of a file are different vary during tests (e.g. compiling
  27114. * containers) mean that the functions inside a file cannot be relied upon to be static.
  27115. *
  27116. * @psalm-param XdebugFunctionCoverageType $functionData
  27117. */
  27118. private function initPreviouslySeenFunction(string $file, string $functionName, array $functionData): void
  27119. {
  27120. foreach ($functionData['branches'] as $branchId => $branchData) {
  27121. if (!isset($this->functionCoverage[$file][$functionName]['branches'][$branchId])) {
  27122. $this->functionCoverage[$file][$functionName]['branches'][$branchId] = $branchData;
  27123. $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
  27124. }
  27125. }
  27126. foreach ($functionData['paths'] as $pathId => $pathData) {
  27127. if (!isset($this->functionCoverage[$file][$functionName]['paths'][$pathId])) {
  27128. $this->functionCoverage[$file][$functionName]['paths'][$pathId] = $pathData;
  27129. $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
  27130. }
  27131. }
  27132. }
  27133. }
  27134. <?php
  27135. declare (strict_types=1);
  27136. /*
  27137. * This file is part of phpunit/php-code-coverage.
  27138. *
  27139. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27140. *
  27141. * For the full copyright and license information, please view the LICENSE
  27142. * file that was distributed with this source code.
  27143. */
  27144. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data;
  27145. use function array_diff;
  27146. use function array_diff_key;
  27147. use function array_flip;
  27148. use function array_intersect;
  27149. use function array_intersect_key;
  27150. use function count;
  27151. use function explode;
  27152. use function file_get_contents;
  27153. use function in_array;
  27154. use function is_file;
  27155. use function preg_replace;
  27156. use function range;
  27157. use function str_ends_with;
  27158. use function str_starts_with;
  27159. use function trim;
  27160. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
  27161. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
  27162. /**
  27163. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  27164. *
  27165. * @psalm-import-type XdebugFunctionsCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
  27166. * @psalm-import-type XdebugCodeCoverageWithoutPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
  27167. * @psalm-import-type XdebugCodeCoverageWithPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
  27168. */
  27169. final class RawCodeCoverageData
  27170. {
  27171. /**
  27172. * @var array<string, array<int>>
  27173. */
  27174. private static array $emptyLineCache = [];
  27175. /**
  27176. * @psalm-var XdebugCodeCoverageWithoutPathCoverageType
  27177. */
  27178. private array $lineCoverage;
  27179. /**
  27180. * @psalm-var array<string, XdebugFunctionsCoverageType>
  27181. */
  27182. private array $functionCoverage;
  27183. /**
  27184. * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $rawCoverage
  27185. */
  27186. public static function fromXdebugWithoutPathCoverage(array $rawCoverage): self
  27187. {
  27188. return new self($rawCoverage, []);
  27189. }
  27190. /**
  27191. * @psalm-param XdebugCodeCoverageWithPathCoverageType $rawCoverage
  27192. */
  27193. public static function fromXdebugWithPathCoverage(array $rawCoverage): self
  27194. {
  27195. $lineCoverage = [];
  27196. $functionCoverage = [];
  27197. foreach ($rawCoverage as $file => $fileCoverageData) {
  27198. // Xdebug annotates the function name of traits, strip that off
  27199. foreach ($fileCoverageData['functions'] as $existingKey => $data) {
  27200. if (str_ends_with($existingKey, '}') && !str_starts_with($existingKey, '{')) {
  27201. // don't want to catch {main}
  27202. $newKey = preg_replace('/\{.*}$/', '', $existingKey);
  27203. $fileCoverageData['functions'][$newKey] = $data;
  27204. unset($fileCoverageData['functions'][$existingKey]);
  27205. }
  27206. }
  27207. $lineCoverage[$file] = $fileCoverageData['lines'];
  27208. $functionCoverage[$file] = $fileCoverageData['functions'];
  27209. }
  27210. return new self($lineCoverage, $functionCoverage);
  27211. }
  27212. public static function fromUncoveredFile(string $filename, FileAnalyser $analyser): self
  27213. {
  27214. $lineCoverage = [];
  27215. foreach ($analyser->executableLinesIn($filename) as $line => $branch) {
  27216. $lineCoverage[$line] = Driver::LINE_NOT_EXECUTED;
  27217. }
  27218. return new self([$filename => $lineCoverage], []);
  27219. }
  27220. /**
  27221. * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $lineCoverage
  27222. * @psalm-param array<string, XdebugFunctionsCoverageType> $functionCoverage
  27223. */
  27224. private function __construct(array $lineCoverage, array $functionCoverage)
  27225. {
  27226. $this->lineCoverage = $lineCoverage;
  27227. $this->functionCoverage = $functionCoverage;
  27228. $this->skipEmptyLines();
  27229. }
  27230. public function clear(): void
  27231. {
  27232. $this->lineCoverage = $this->functionCoverage = [];
  27233. }
  27234. /**
  27235. * @psalm-return XdebugCodeCoverageWithoutPathCoverageType
  27236. */
  27237. public function lineCoverage(): array
  27238. {
  27239. return $this->lineCoverage;
  27240. }
  27241. /**
  27242. * @psalm-return array<string, XdebugFunctionsCoverageType>
  27243. */
  27244. public function functionCoverage(): array
  27245. {
  27246. return $this->functionCoverage;
  27247. }
  27248. public function removeCoverageDataForFile(string $filename): void
  27249. {
  27250. unset($this->lineCoverage[$filename], $this->functionCoverage[$filename]);
  27251. }
  27252. /**
  27253. * @param int[] $lines
  27254. */
  27255. public function keepLineCoverageDataOnlyForLines(string $filename, array $lines): void
  27256. {
  27257. if (!isset($this->lineCoverage[$filename])) {
  27258. return;
  27259. }
  27260. $this->lineCoverage[$filename] = array_intersect_key($this->lineCoverage[$filename], array_flip($lines));
  27261. }
  27262. /**
  27263. * @param int[] $linesToBranchMap
  27264. */
  27265. public function markExecutableLineByBranch(string $filename, array $linesToBranchMap): void
  27266. {
  27267. if (!isset($this->lineCoverage[$filename])) {
  27268. return;
  27269. }
  27270. $linesByBranch = [];
  27271. foreach ($linesToBranchMap as $line => $branch) {
  27272. $linesByBranch[$branch][] = $line;
  27273. }
  27274. foreach ($this->lineCoverage[$filename] as $line => $lineStatus) {
  27275. if (!isset($linesToBranchMap[$line])) {
  27276. continue;
  27277. }
  27278. $branch = $linesToBranchMap[$line];
  27279. if (!isset($linesByBranch[$branch])) {
  27280. continue;
  27281. }
  27282. foreach ($linesByBranch[$branch] as $lineInBranch) {
  27283. $this->lineCoverage[$filename][$lineInBranch] = $lineStatus;
  27284. }
  27285. if (Driver::LINE_EXECUTED === $lineStatus) {
  27286. unset($linesByBranch[$branch]);
  27287. }
  27288. }
  27289. }
  27290. /**
  27291. * @param int[] $lines
  27292. */
  27293. public function keepFunctionCoverageDataOnlyForLines(string $filename, array $lines): void
  27294. {
  27295. if (!isset($this->functionCoverage[$filename])) {
  27296. return;
  27297. }
  27298. foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
  27299. foreach ($functionData['branches'] as $branchId => $branch) {
  27300. if (count(array_diff(range($branch['line_start'], $branch['line_end']), $lines)) > 0) {
  27301. unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
  27302. foreach ($functionData['paths'] as $pathId => $path) {
  27303. if (in_array($branchId, $path['path'], \true)) {
  27304. unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
  27305. }
  27306. }
  27307. }
  27308. }
  27309. }
  27310. }
  27311. /**
  27312. * @param int[] $lines
  27313. */
  27314. public function removeCoverageDataForLines(string $filename, array $lines): void
  27315. {
  27316. if (empty($lines)) {
  27317. return;
  27318. }
  27319. if (!isset($this->lineCoverage[$filename])) {
  27320. return;
  27321. }
  27322. $this->lineCoverage[$filename] = array_diff_key($this->lineCoverage[$filename], array_flip($lines));
  27323. if (isset($this->functionCoverage[$filename])) {
  27324. foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
  27325. foreach ($functionData['branches'] as $branchId => $branch) {
  27326. if (count(array_intersect($lines, range($branch['line_start'], $branch['line_end']))) > 0) {
  27327. unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
  27328. foreach ($functionData['paths'] as $pathId => $path) {
  27329. if (in_array($branchId, $path['path'], \true)) {
  27330. unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
  27331. }
  27332. }
  27333. }
  27334. }
  27335. }
  27336. }
  27337. }
  27338. /**
  27339. * At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has
  27340. * e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine
  27341. * implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines
  27342. * are skipped over for coverage purposes.
  27343. *
  27344. * @see https://github.com/sebastianbergmann/php-code-coverage/issues/799
  27345. */
  27346. private function skipEmptyLines(): void
  27347. {
  27348. foreach ($this->lineCoverage as $filename => $coverage) {
  27349. foreach ($this->getEmptyLinesForFile($filename) as $emptyLine) {
  27350. unset($this->lineCoverage[$filename][$emptyLine]);
  27351. }
  27352. }
  27353. }
  27354. private function getEmptyLinesForFile(string $filename): array
  27355. {
  27356. if (!isset(self::$emptyLineCache[$filename])) {
  27357. self::$emptyLineCache[$filename] = [];
  27358. if (is_file($filename)) {
  27359. $sourceLines = explode("\n", file_get_contents($filename));
  27360. foreach ($sourceLines as $line => $source) {
  27361. if (trim($source) === '') {
  27362. self::$emptyLineCache[$filename][] = $line + 1;
  27363. }
  27364. }
  27365. }
  27366. }
  27367. return self::$emptyLineCache[$filename];
  27368. }
  27369. }
  27370. <?php
  27371. declare (strict_types=1);
  27372. /*
  27373. * This file is part of phpunit/php-code-coverage.
  27374. *
  27375. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27376. *
  27377. * For the full copyright and license information, please view the LICENSE
  27378. * file that was distributed with this source code.
  27379. */
  27380. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27381. use function sprintf;
  27382. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\BranchAndPathCoverageNotSupportedException;
  27383. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
  27384. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\DeadCodeDetectionNotSupportedException;
  27385. /**
  27386. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  27387. */
  27388. abstract class Driver
  27389. {
  27390. /**
  27391. * @var int
  27392. *
  27393. * @see http://xdebug.org/docs/code_coverage
  27394. */
  27395. public const LINE_NOT_EXECUTABLE = -2;
  27396. /**
  27397. * @var int
  27398. *
  27399. * @see http://xdebug.org/docs/code_coverage
  27400. */
  27401. public const LINE_NOT_EXECUTED = -1;
  27402. /**
  27403. * @var int
  27404. *
  27405. * @see http://xdebug.org/docs/code_coverage
  27406. */
  27407. public const LINE_EXECUTED = 1;
  27408. /**
  27409. * @var int
  27410. *
  27411. * @see http://xdebug.org/docs/code_coverage
  27412. */
  27413. public const BRANCH_NOT_HIT = 0;
  27414. /**
  27415. * @var int
  27416. *
  27417. * @see http://xdebug.org/docs/code_coverage
  27418. */
  27419. public const BRANCH_HIT = 1;
  27420. private bool $collectBranchAndPathCoverage = \false;
  27421. private bool $detectDeadCode = \false;
  27422. public function canCollectBranchAndPathCoverage(): bool
  27423. {
  27424. return \false;
  27425. }
  27426. public function collectsBranchAndPathCoverage(): bool
  27427. {
  27428. return $this->collectBranchAndPathCoverage;
  27429. }
  27430. /**
  27431. * @throws BranchAndPathCoverageNotSupportedException
  27432. */
  27433. public function enableBranchAndPathCoverage(): void
  27434. {
  27435. if (!$this->canCollectBranchAndPathCoverage()) {
  27436. throw new BranchAndPathCoverageNotSupportedException(sprintf('%s does not support branch and path coverage', $this->nameAndVersion()));
  27437. }
  27438. $this->collectBranchAndPathCoverage = \true;
  27439. }
  27440. public function disableBranchAndPathCoverage(): void
  27441. {
  27442. $this->collectBranchAndPathCoverage = \false;
  27443. }
  27444. public function canDetectDeadCode(): bool
  27445. {
  27446. return \false;
  27447. }
  27448. public function detectsDeadCode(): bool
  27449. {
  27450. return $this->detectDeadCode;
  27451. }
  27452. /**
  27453. * @throws DeadCodeDetectionNotSupportedException
  27454. */
  27455. public function enableDeadCodeDetection(): void
  27456. {
  27457. if (!$this->canDetectDeadCode()) {
  27458. throw new DeadCodeDetectionNotSupportedException(sprintf('%s does not support dead code detection', $this->nameAndVersion()));
  27459. }
  27460. $this->detectDeadCode = \true;
  27461. }
  27462. public function disableDeadCodeDetection(): void
  27463. {
  27464. $this->detectDeadCode = \false;
  27465. }
  27466. abstract public function nameAndVersion(): string;
  27467. abstract public function start(): void;
  27468. abstract public function stop(): RawCodeCoverageData;
  27469. }
  27470. <?php
  27471. declare (strict_types=1);
  27472. /*
  27473. * This file is part of phpunit/php-code-coverage.
  27474. *
  27475. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27476. *
  27477. * For the full copyright and license information, please view the LICENSE
  27478. * file that was distributed with this source code.
  27479. */
  27480. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27481. use const pcov\inclusive;
  27482. use function array_intersect;
  27483. use function extension_loaded;
  27484. use function pcov\clear;
  27485. use function pcov\collect;
  27486. use function pcov\start;
  27487. use function pcov\stop;
  27488. use function pcov\waiting;
  27489. use function phpversion;
  27490. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
  27491. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  27492. /**
  27493. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  27494. */
  27495. final class PcovDriver extends Driver
  27496. {
  27497. private readonly Filter $filter;
  27498. /**
  27499. * @throws PcovNotAvailableException
  27500. */
  27501. public function __construct(Filter $filter)
  27502. {
  27503. $this->ensurePcovIsAvailable();
  27504. $this->filter = $filter;
  27505. }
  27506. public function start(): void
  27507. {
  27508. start();
  27509. }
  27510. public function stop(): RawCodeCoverageData
  27511. {
  27512. stop();
  27513. $filesToCollectCoverageFor = waiting();
  27514. $collected = [];
  27515. if ($filesToCollectCoverageFor) {
  27516. if (!$this->filter->isEmpty()) {
  27517. $filesToCollectCoverageFor = array_intersect($filesToCollectCoverageFor, $this->filter->files());
  27518. }
  27519. $collected = collect(inclusive, $filesToCollectCoverageFor);
  27520. clear();
  27521. }
  27522. return RawCodeCoverageData::fromXdebugWithoutPathCoverage($collected);
  27523. }
  27524. public function nameAndVersion(): string
  27525. {
  27526. return 'PCOV ' . phpversion('pcov');
  27527. }
  27528. /**
  27529. * @throws PcovNotAvailableException
  27530. */
  27531. private function ensurePcovIsAvailable(): void
  27532. {
  27533. if (!extension_loaded('pcov')) {
  27534. throw new PcovNotAvailableException();
  27535. }
  27536. }
  27537. }
  27538. <?php
  27539. declare (strict_types=1);
  27540. /*
  27541. * This file is part of phpunit/php-code-coverage.
  27542. *
  27543. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27544. *
  27545. * For the full copyright and license information, please view the LICENSE
  27546. * file that was distributed with this source code.
  27547. */
  27548. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27549. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  27550. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\NoCodeCoverageDriverAvailableException;
  27551. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
  27552. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  27553. final class Selector
  27554. {
  27555. /**
  27556. * @throws NoCodeCoverageDriverAvailableException
  27557. * @throws PcovNotAvailableException
  27558. * @throws XdebugNotAvailableException
  27559. * @throws XdebugNotEnabledException
  27560. */
  27561. public function forLineCoverage(Filter $filter): Driver
  27562. {
  27563. $runtime = new Runtime();
  27564. if ($runtime->hasPCOV()) {
  27565. return new PcovDriver($filter);
  27566. }
  27567. if ($runtime->hasXdebug()) {
  27568. $driver = new XdebugDriver($filter);
  27569. $driver->enableDeadCodeDetection();
  27570. return $driver;
  27571. }
  27572. throw new NoCodeCoverageDriverAvailableException();
  27573. }
  27574. /**
  27575. * @throws NoCodeCoverageDriverWithPathCoverageSupportAvailableException
  27576. * @throws XdebugNotAvailableException
  27577. * @throws XdebugNotEnabledException
  27578. */
  27579. public function forLineAndPathCoverage(Filter $filter): Driver
  27580. {
  27581. if ((new Runtime())->hasXdebug()) {
  27582. $driver = new XdebugDriver($filter);
  27583. $driver->enableDeadCodeDetection();
  27584. $driver->enableBranchAndPathCoverage();
  27585. return $driver;
  27586. }
  27587. throw new NoCodeCoverageDriverWithPathCoverageSupportAvailableException();
  27588. }
  27589. }
  27590. <?php
  27591. declare (strict_types=1);
  27592. /*
  27593. * This file is part of phpunit/php-code-coverage.
  27594. *
  27595. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27596. *
  27597. * For the full copyright and license information, please view the LICENSE
  27598. * file that was distributed with this source code.
  27599. */
  27600. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27601. use const XDEBUG_CC_BRANCH_CHECK;
  27602. use const XDEBUG_CC_DEAD_CODE;
  27603. use const XDEBUG_CC_UNUSED;
  27604. use const XDEBUG_FILTER_CODE_COVERAGE;
  27605. use const XDEBUG_PATH_INCLUDE;
  27606. use function explode;
  27607. use function extension_loaded;
  27608. use function getenv;
  27609. use function in_array;
  27610. use function ini_get;
  27611. use function phpversion;
  27612. use function version_compare;
  27613. use function xdebug_get_code_coverage;
  27614. use function xdebug_info;
  27615. use function xdebug_set_filter;
  27616. use function xdebug_start_code_coverage;
  27617. use function xdebug_stop_code_coverage;
  27618. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
  27619. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  27620. /**
  27621. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  27622. *
  27623. * @see https://xdebug.org/docs/code_coverage#xdebug_get_code_coverage
  27624. *
  27625. * @psalm-type XdebugLinesCoverageType = array<int, int>
  27626. * @psalm-type XdebugBranchCoverageType = array{
  27627. * op_start: int,
  27628. * op_end: int,
  27629. * line_start: int,
  27630. * line_end: int,
  27631. * hit: int,
  27632. * out: array<int, int>,
  27633. * out_hit: array<int, int>,
  27634. * }
  27635. * @psalm-type XdebugPathCoverageType = array{
  27636. * path: array<int, int>,
  27637. * hit: int,
  27638. * }
  27639. * @psalm-type XdebugFunctionCoverageType = array{
  27640. * branches: array<int, XdebugBranchCoverageType>,
  27641. * paths: array<int, XdebugPathCoverageType>,
  27642. * }
  27643. * @psalm-type XdebugFunctionsCoverageType = array<string, XdebugFunctionCoverageType>
  27644. * @psalm-type XdebugPathAndBranchesCoverageType = array{
  27645. * lines: XdebugLinesCoverageType,
  27646. * functions: XdebugFunctionsCoverageType,
  27647. * }
  27648. * @psalm-type XdebugCodeCoverageWithoutPathCoverageType = array<string, XdebugLinesCoverageType>
  27649. * @psalm-type XdebugCodeCoverageWithPathCoverageType = array<string, XdebugPathAndBranchesCoverageType>
  27650. */
  27651. final class XdebugDriver extends Driver
  27652. {
  27653. /**
  27654. * @throws XdebugNotAvailableException
  27655. * @throws XdebugNotEnabledException
  27656. */
  27657. public function __construct(Filter $filter)
  27658. {
  27659. $this->ensureXdebugIsAvailable();
  27660. $this->ensureXdebugCodeCoverageFeatureIsEnabled();
  27661. if (!$filter->isEmpty()) {
  27662. xdebug_set_filter(XDEBUG_FILTER_CODE_COVERAGE, XDEBUG_PATH_INCLUDE, $filter->files());
  27663. }
  27664. }
  27665. public function canCollectBranchAndPathCoverage(): bool
  27666. {
  27667. return \true;
  27668. }
  27669. public function canDetectDeadCode(): bool
  27670. {
  27671. return \true;
  27672. }
  27673. public function start(): void
  27674. {
  27675. $flags = XDEBUG_CC_UNUSED;
  27676. if ($this->detectsDeadCode() || $this->collectsBranchAndPathCoverage()) {
  27677. $flags |= XDEBUG_CC_DEAD_CODE;
  27678. }
  27679. if ($this->collectsBranchAndPathCoverage()) {
  27680. $flags |= XDEBUG_CC_BRANCH_CHECK;
  27681. }
  27682. xdebug_start_code_coverage($flags);
  27683. }
  27684. public function stop(): RawCodeCoverageData
  27685. {
  27686. $data = xdebug_get_code_coverage();
  27687. xdebug_stop_code_coverage();
  27688. if ($this->collectsBranchAndPathCoverage()) {
  27689. /* @var XdebugCodeCoverageWithPathCoverageType $data */
  27690. return RawCodeCoverageData::fromXdebugWithPathCoverage($data);
  27691. }
  27692. /* @var XdebugCodeCoverageWithoutPathCoverageType $data */
  27693. return RawCodeCoverageData::fromXdebugWithoutPathCoverage($data);
  27694. }
  27695. public function nameAndVersion(): string
  27696. {
  27697. return 'Xdebug ' . phpversion('xdebug');
  27698. }
  27699. /**
  27700. * @throws XdebugNotAvailableException
  27701. */
  27702. private function ensureXdebugIsAvailable(): void
  27703. {
  27704. if (!extension_loaded('xdebug')) {
  27705. throw new XdebugNotAvailableException();
  27706. }
  27707. }
  27708. /**
  27709. * @throws XdebugNotEnabledException
  27710. */
  27711. private function ensureXdebugCodeCoverageFeatureIsEnabled(): void
  27712. {
  27713. if (version_compare(phpversion('xdebug'), '3.1', '>=')) {
  27714. if (!in_array('coverage', xdebug_info('mode'), \true)) {
  27715. throw new XdebugNotEnabledException();
  27716. }
  27717. return;
  27718. }
  27719. $mode = getenv('XDEBUG_MODE');
  27720. if ($mode === \false || $mode === '') {
  27721. $mode = ini_get('xdebug.mode');
  27722. }
  27723. if ($mode === \false || !in_array('coverage', explode(',', $mode), \true)) {
  27724. throw new XdebugNotEnabledException();
  27725. }
  27726. }
  27727. }
  27728. <?php
  27729. declare (strict_types=1);
  27730. /*
  27731. * This file is part of phpunit/php-code-coverage.
  27732. *
  27733. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27734. *
  27735. * For the full copyright and license information, please view the LICENSE
  27736. * file that was distributed with this source code.
  27737. */
  27738. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27739. use RuntimeException;
  27740. final class BranchAndPathCoverageNotSupportedException extends RuntimeException implements Exception
  27741. {
  27742. }
  27743. <?php
  27744. declare (strict_types=1);
  27745. /*
  27746. * This file is part of phpunit/php-code-coverage.
  27747. *
  27748. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27749. *
  27750. * For the full copyright and license information, please view the LICENSE
  27751. * file that was distributed with this source code.
  27752. */
  27753. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27754. use RuntimeException;
  27755. final class DeadCodeDetectionNotSupportedException extends RuntimeException implements Exception
  27756. {
  27757. }
  27758. <?php
  27759. declare (strict_types=1);
  27760. /*
  27761. * This file is part of phpunit/php-code-coverage.
  27762. *
  27763. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27764. *
  27765. * For the full copyright and license information, please view the LICENSE
  27766. * file that was distributed with this source code.
  27767. */
  27768. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
  27769. use RuntimeException;
  27770. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  27771. final class DirectoryCouldNotBeCreatedException extends RuntimeException implements Exception
  27772. {
  27773. }
  27774. <?php
  27775. declare (strict_types=1);
  27776. /*
  27777. * This file is part of phpunit/php-code-coverage.
  27778. *
  27779. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27780. *
  27781. * For the full copyright and license information, please view the LICENSE
  27782. * file that was distributed with this source code.
  27783. */
  27784. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27785. use Throwable;
  27786. interface Exception extends Throwable
  27787. {
  27788. }
  27789. <?php
  27790. declare (strict_types=1);
  27791. /*
  27792. * This file is part of phpunit/php-code-coverage.
  27793. *
  27794. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27795. *
  27796. * For the full copyright and license information, please view the LICENSE
  27797. * file that was distributed with this source code.
  27798. */
  27799. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27800. use RuntimeException;
  27801. final class FileCouldNotBeWrittenException extends RuntimeException implements Exception
  27802. {
  27803. }
  27804. <?php
  27805. declare (strict_types=1);
  27806. /*
  27807. * This file is part of phpunit/php-code-coverage.
  27808. *
  27809. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27810. *
  27811. * For the full copyright and license information, please view the LICENSE
  27812. * file that was distributed with this source code.
  27813. */
  27814. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27815. final class InvalidArgumentException extends \InvalidArgumentException implements Exception
  27816. {
  27817. }
  27818. <?php
  27819. declare (strict_types=1);
  27820. /*
  27821. * This file is part of phpunit/php-code-coverage.
  27822. *
  27823. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27824. *
  27825. * For the full copyright and license information, please view the LICENSE
  27826. * file that was distributed with this source code.
  27827. */
  27828. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27829. use RuntimeException;
  27830. final class NoCodeCoverageDriverAvailableException extends RuntimeException implements Exception
  27831. {
  27832. public function __construct()
  27833. {
  27834. parent::__construct('No code coverage driver available');
  27835. }
  27836. }
  27837. <?php
  27838. declare (strict_types=1);
  27839. /*
  27840. * This file is part of phpunit/php-code-coverage.
  27841. *
  27842. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27843. *
  27844. * For the full copyright and license information, please view the LICENSE
  27845. * file that was distributed with this source code.
  27846. */
  27847. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27848. use RuntimeException;
  27849. final class NoCodeCoverageDriverWithPathCoverageSupportAvailableException extends RuntimeException implements Exception
  27850. {
  27851. public function __construct()
  27852. {
  27853. parent::__construct('No code coverage driver with path coverage support available');
  27854. }
  27855. }
  27856. <?php
  27857. declare (strict_types=1);
  27858. /*
  27859. * This file is part of phpunit/php-code-coverage.
  27860. *
  27861. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27862. *
  27863. * For the full copyright and license information, please view the LICENSE
  27864. * file that was distributed with this source code.
  27865. */
  27866. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27867. use RuntimeException;
  27868. final class ParserException extends RuntimeException implements Exception
  27869. {
  27870. }
  27871. <?php
  27872. declare (strict_types=1);
  27873. /*
  27874. * This file is part of phpunit/php-code-coverage.
  27875. *
  27876. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27877. *
  27878. * For the full copyright and license information, please view the LICENSE
  27879. * file that was distributed with this source code.
  27880. */
  27881. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27882. use function sprintf;
  27883. use RuntimeException;
  27884. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  27885. final class PathExistsButIsNotDirectoryException extends RuntimeException implements Exception
  27886. {
  27887. public function __construct(string $path)
  27888. {
  27889. parent::__construct(sprintf('"%s" exists but is not a directory', $path));
  27890. }
  27891. }
  27892. <?php
  27893. declare (strict_types=1);
  27894. /*
  27895. * This file is part of phpunit/php-code-coverage.
  27896. *
  27897. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27898. *
  27899. * For the full copyright and license information, please view the LICENSE
  27900. * file that was distributed with this source code.
  27901. */
  27902. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  27903. use RuntimeException;
  27904. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  27905. final class PcovNotAvailableException extends RuntimeException implements Exception
  27906. {
  27907. public function __construct()
  27908. {
  27909. parent::__construct('The PCOV extension is not available');
  27910. }
  27911. }
  27912. <?php
  27913. declare (strict_types=1);
  27914. /*
  27915. * This file is part of phpunit/php-code-coverage.
  27916. *
  27917. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27918. *
  27919. * For the full copyright and license information, please view the LICENSE
  27920. * file that was distributed with this source code.
  27921. */
  27922. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27923. use RuntimeException;
  27924. final class ReflectionException extends RuntimeException implements Exception
  27925. {
  27926. }
  27927. <?php
  27928. declare (strict_types=1);
  27929. /*
  27930. * This file is part of phpunit/php-code-coverage.
  27931. *
  27932. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27933. *
  27934. * For the full copyright and license information, please view the LICENSE
  27935. * file that was distributed with this source code.
  27936. */
  27937. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27938. use RuntimeException;
  27939. final class ReportAlreadyFinalizedException extends RuntimeException implements Exception
  27940. {
  27941. public function __construct()
  27942. {
  27943. parent::__construct('The code coverage report has already been finalized');
  27944. }
  27945. }
  27946. <?php
  27947. declare (strict_types=1);
  27948. /*
  27949. * This file is part of phpunit/php-code-coverage.
  27950. *
  27951. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27952. *
  27953. * For the full copyright and license information, please view the LICENSE
  27954. * file that was distributed with this source code.
  27955. */
  27956. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27957. use RuntimeException;
  27958. final class StaticAnalysisCacheNotConfiguredException extends RuntimeException implements Exception
  27959. {
  27960. }
  27961. <?php
  27962. declare (strict_types=1);
  27963. /*
  27964. * This file is part of phpunit/php-code-coverage.
  27965. *
  27966. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27967. *
  27968. * For the full copyright and license information, please view the LICENSE
  27969. * file that was distributed with this source code.
  27970. */
  27971. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27972. use RuntimeException;
  27973. final class TestIdMissingException extends RuntimeException implements Exception
  27974. {
  27975. public function __construct()
  27976. {
  27977. parent::__construct('Test ID is missing');
  27978. }
  27979. }
  27980. <?php
  27981. declare (strict_types=1);
  27982. /*
  27983. * This file is part of phpunit/php-code-coverage.
  27984. *
  27985. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27986. *
  27987. * For the full copyright and license information, please view the LICENSE
  27988. * file that was distributed with this source code.
  27989. */
  27990. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  27991. use RuntimeException;
  27992. final class UnintentionallyCoveredCodeException extends RuntimeException implements Exception
  27993. {
  27994. /**
  27995. * @var list<string>
  27996. */
  27997. private readonly array $unintentionallyCoveredUnits;
  27998. /**
  27999. * @param list<string> $unintentionallyCoveredUnits
  28000. */
  28001. public function __construct(array $unintentionallyCoveredUnits)
  28002. {
  28003. $this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits;
  28004. parent::__construct($this->toString());
  28005. }
  28006. /**
  28007. * @return list<string>
  28008. */
  28009. public function getUnintentionallyCoveredUnits(): array
  28010. {
  28011. return $this->unintentionallyCoveredUnits;
  28012. }
  28013. private function toString(): string
  28014. {
  28015. $message = '';
  28016. foreach ($this->unintentionallyCoveredUnits as $unit) {
  28017. $message .= '- ' . $unit . "\n";
  28018. }
  28019. return $message;
  28020. }
  28021. }
  28022. <?php
  28023. declare (strict_types=1);
  28024. /*
  28025. * This file is part of phpunit/php-code-coverage.
  28026. *
  28027. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28028. *
  28029. * For the full copyright and license information, please view the LICENSE
  28030. * file that was distributed with this source code.
  28031. */
  28032. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  28033. use function sprintf;
  28034. use RuntimeException;
  28035. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  28036. final class WriteOperationFailedException extends RuntimeException implements Exception
  28037. {
  28038. public function __construct(string $path)
  28039. {
  28040. parent::__construct(sprintf('Cannot write to "%s"', $path));
  28041. }
  28042. }
  28043. <?php
  28044. declare (strict_types=1);
  28045. /*
  28046. * This file is part of phpunit/php-code-coverage.
  28047. *
  28048. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28049. *
  28050. * For the full copyright and license information, please view the LICENSE
  28051. * file that was distributed with this source code.
  28052. */
  28053. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  28054. use RuntimeException;
  28055. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  28056. final class XdebugNotAvailableException extends RuntimeException implements Exception
  28057. {
  28058. public function __construct()
  28059. {
  28060. parent::__construct('The Xdebug extension is not available');
  28061. }
  28062. }
  28063. <?php
  28064. declare (strict_types=1);
  28065. /*
  28066. * This file is part of phpunit/php-code-coverage.
  28067. *
  28068. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28069. *
  28070. * For the full copyright and license information, please view the LICENSE
  28071. * file that was distributed with this source code.
  28072. */
  28073. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
  28074. use RuntimeException;
  28075. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
  28076. final class XdebugNotEnabledException extends RuntimeException implements Exception
  28077. {
  28078. public function __construct()
  28079. {
  28080. parent::__construct('XDEBUG_MODE=coverage (environment variable) or xdebug.mode=coverage (PHP configuration setting) has to be set');
  28081. }
  28082. }
  28083. <?php
  28084. declare (strict_types=1);
  28085. /*
  28086. * This file is part of phpunit/php-code-coverage.
  28087. *
  28088. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28089. *
  28090. * For the full copyright and license information, please view the LICENSE
  28091. * file that was distributed with this source code.
  28092. */
  28093. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  28094. use RuntimeException;
  28095. final class XmlException extends RuntimeException implements Exception
  28096. {
  28097. }
  28098. <?php
  28099. declare (strict_types=1);
  28100. /*
  28101. * This file is part of phpunit/php-code-coverage.
  28102. *
  28103. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28104. *
  28105. * For the full copyright and license information, please view the LICENSE
  28106. * file that was distributed with this source code.
  28107. */
  28108. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  28109. use function array_keys;
  28110. use function is_file;
  28111. use function realpath;
  28112. use function str_contains;
  28113. use function str_starts_with;
  28114. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  28115. final class Filter
  28116. {
  28117. /**
  28118. * @psalm-var array<string,true>
  28119. */
  28120. private array $files = [];
  28121. /**
  28122. * @psalm-var array<string,bool>
  28123. */
  28124. private array $isFileCache = [];
  28125. /**
  28126. * @deprecated
  28127. */
  28128. public function includeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
  28129. {
  28130. foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) {
  28131. $this->includeFile($file);
  28132. }
  28133. }
  28134. /**
  28135. * @psalm-param list<string> $files
  28136. */
  28137. public function includeFiles(array $filenames): void
  28138. {
  28139. foreach ($filenames as $filename) {
  28140. $this->includeFile($filename);
  28141. }
  28142. }
  28143. public function includeFile(string $filename): void
  28144. {
  28145. $filename = realpath($filename);
  28146. if (!$filename) {
  28147. return;
  28148. }
  28149. $this->files[$filename] = \true;
  28150. }
  28151. /**
  28152. * @deprecated
  28153. */
  28154. public function excludeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
  28155. {
  28156. foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) {
  28157. $this->excludeFile($file);
  28158. }
  28159. }
  28160. /**
  28161. * @deprecated
  28162. */
  28163. public function excludeFile(string $filename): void
  28164. {
  28165. $filename = realpath($filename);
  28166. if (!$filename || !isset($this->files[$filename])) {
  28167. return;
  28168. }
  28169. unset($this->files[$filename]);
  28170. }
  28171. public function isFile(string $filename): bool
  28172. {
  28173. if (isset($this->isFileCache[$filename])) {
  28174. return $this->isFileCache[$filename];
  28175. }
  28176. if ($filename === '-' || str_starts_with($filename, 'vfs://') || str_contains($filename, 'xdebug://debug-eval') || str_contains($filename, 'eval()\'d code') || str_contains($filename, 'runtime-created function') || str_contains($filename, 'runkit created function') || str_contains($filename, 'assert code') || str_contains($filename, 'regexp code') || str_contains($filename, 'Standard input code')) {
  28177. $isFile = \false;
  28178. } else {
  28179. $isFile = is_file($filename);
  28180. }
  28181. $this->isFileCache[$filename] = $isFile;
  28182. return $isFile;
  28183. }
  28184. public function isExcluded(string $filename): bool
  28185. {
  28186. return !isset($this->files[$filename]) || !$this->isFile($filename);
  28187. }
  28188. /**
  28189. * @psalm-return list<string>
  28190. */
  28191. public function files(): array
  28192. {
  28193. return array_keys($this->files);
  28194. }
  28195. public function isEmpty(): bool
  28196. {
  28197. return empty($this->files);
  28198. }
  28199. }
  28200. BSD 3-Clause License
  28201. Copyright (c) 2009-2024, Sebastian Bergmann
  28202. All rights reserved.
  28203. Redistribution and use in source and binary forms, with or without
  28204. modification, are permitted provided that the following conditions are met:
  28205. 1. Redistributions of source code must retain the above copyright notice, this
  28206. list of conditions and the following disclaimer.
  28207. 2. Redistributions in binary form must reproduce the above copyright notice,
  28208. this list of conditions and the following disclaimer in the documentation
  28209. and/or other materials provided with the distribution.
  28210. 3. Neither the name of the copyright holder nor the names of its
  28211. contributors may be used to endorse or promote products derived from
  28212. this software without specific prior written permission.
  28213. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28214. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28215. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28216. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  28217. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28218. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  28219. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28220. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28221. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28222. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28223. <?php
  28224. declare (strict_types=1);
  28225. /*
  28226. * This file is part of phpunit/php-code-coverage.
  28227. *
  28228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28229. *
  28230. * For the full copyright and license information, please view the LICENSE
  28231. * file that was distributed with this source code.
  28232. */
  28233. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  28234. use const DIRECTORY_SEPARATOR;
  28235. use function array_merge;
  28236. use function str_ends_with;
  28237. use function str_replace;
  28238. use function substr;
  28239. use Countable;
  28240. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
  28241. /**
  28242. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  28243. *
  28244. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  28245. * @psalm-import-type ProcessedFunctionType from \SebastianBergmann\CodeCoverage\Node\File
  28246. * @psalm-import-type ProcessedClassType from \SebastianBergmann\CodeCoverage\Node\File
  28247. * @psalm-import-type ProcessedTraitType from \SebastianBergmann\CodeCoverage\Node\File
  28248. */
  28249. abstract class AbstractNode implements Countable
  28250. {
  28251. private readonly string $name;
  28252. private string $pathAsString;
  28253. private array $pathAsArray;
  28254. private readonly ?AbstractNode $parent;
  28255. private string $id;
  28256. public function __construct(string $name, ?self $parent = null)
  28257. {
  28258. if (str_ends_with($name, DIRECTORY_SEPARATOR)) {
  28259. $name = substr($name, 0, -1);
  28260. }
  28261. $this->name = $name;
  28262. $this->parent = $parent;
  28263. $this->processId();
  28264. $this->processPath();
  28265. }
  28266. public function name(): string
  28267. {
  28268. return $this->name;
  28269. }
  28270. public function id(): string
  28271. {
  28272. return $this->id;
  28273. }
  28274. public function pathAsString(): string
  28275. {
  28276. return $this->pathAsString;
  28277. }
  28278. public function pathAsArray(): array
  28279. {
  28280. return $this->pathAsArray;
  28281. }
  28282. public function parent(): ?self
  28283. {
  28284. return $this->parent;
  28285. }
  28286. public function percentageOfTestedClasses(): Percentage
  28287. {
  28288. return Percentage::fromFractionAndTotal($this->numberOfTestedClasses(), $this->numberOfClasses());
  28289. }
  28290. public function percentageOfTestedTraits(): Percentage
  28291. {
  28292. return Percentage::fromFractionAndTotal($this->numberOfTestedTraits(), $this->numberOfTraits());
  28293. }
  28294. public function percentageOfTestedClassesAndTraits(): Percentage
  28295. {
  28296. return Percentage::fromFractionAndTotal($this->numberOfTestedClassesAndTraits(), $this->numberOfClassesAndTraits());
  28297. }
  28298. public function percentageOfTestedFunctions(): Percentage
  28299. {
  28300. return Percentage::fromFractionAndTotal($this->numberOfTestedFunctions(), $this->numberOfFunctions());
  28301. }
  28302. public function percentageOfTestedMethods(): Percentage
  28303. {
  28304. return Percentage::fromFractionAndTotal($this->numberOfTestedMethods(), $this->numberOfMethods());
  28305. }
  28306. public function percentageOfTestedFunctionsAndMethods(): Percentage
  28307. {
  28308. return Percentage::fromFractionAndTotal($this->numberOfTestedFunctionsAndMethods(), $this->numberOfFunctionsAndMethods());
  28309. }
  28310. public function percentageOfExecutedLines(): Percentage
  28311. {
  28312. return Percentage::fromFractionAndTotal($this->numberOfExecutedLines(), $this->numberOfExecutableLines());
  28313. }
  28314. public function percentageOfExecutedBranches(): Percentage
  28315. {
  28316. return Percentage::fromFractionAndTotal($this->numberOfExecutedBranches(), $this->numberOfExecutableBranches());
  28317. }
  28318. public function percentageOfExecutedPaths(): Percentage
  28319. {
  28320. return Percentage::fromFractionAndTotal($this->numberOfExecutedPaths(), $this->numberOfExecutablePaths());
  28321. }
  28322. public function numberOfClassesAndTraits(): int
  28323. {
  28324. return $this->numberOfClasses() + $this->numberOfTraits();
  28325. }
  28326. public function numberOfTestedClassesAndTraits(): int
  28327. {
  28328. return $this->numberOfTestedClasses() + $this->numberOfTestedTraits();
  28329. }
  28330. public function classesAndTraits(): array
  28331. {
  28332. return array_merge($this->classes(), $this->traits());
  28333. }
  28334. public function numberOfFunctionsAndMethods(): int
  28335. {
  28336. return $this->numberOfFunctions() + $this->numberOfMethods();
  28337. }
  28338. public function numberOfTestedFunctionsAndMethods(): int
  28339. {
  28340. return $this->numberOfTestedFunctions() + $this->numberOfTestedMethods();
  28341. }
  28342. /**
  28343. * @psalm-return array<string, ProcessedClassType>
  28344. */
  28345. abstract public function classes(): array;
  28346. /**
  28347. * @psalm-return array<string, ProcessedTraitType>
  28348. */
  28349. abstract public function traits(): array;
  28350. /**
  28351. * @psalm-return array<string, ProcessedFunctionType>
  28352. */
  28353. abstract public function functions(): array;
  28354. /**
  28355. * @psalm-return LinesOfCodeType
  28356. */
  28357. abstract public function linesOfCode(): array;
  28358. abstract public function numberOfExecutableLines(): int;
  28359. abstract public function numberOfExecutedLines(): int;
  28360. abstract public function numberOfExecutableBranches(): int;
  28361. abstract public function numberOfExecutedBranches(): int;
  28362. abstract public function numberOfExecutablePaths(): int;
  28363. abstract public function numberOfExecutedPaths(): int;
  28364. abstract public function numberOfClasses(): int;
  28365. abstract public function numberOfTestedClasses(): int;
  28366. abstract public function numberOfTraits(): int;
  28367. abstract public function numberOfTestedTraits(): int;
  28368. abstract public function numberOfMethods(): int;
  28369. abstract public function numberOfTestedMethods(): int;
  28370. abstract public function numberOfFunctions(): int;
  28371. abstract public function numberOfTestedFunctions(): int;
  28372. private function processId(): void
  28373. {
  28374. if ($this->parent === null) {
  28375. $this->id = 'index';
  28376. return;
  28377. }
  28378. $parentId = $this->parent->id();
  28379. if ($parentId === 'index') {
  28380. $this->id = str_replace(':', '_', $this->name);
  28381. } else {
  28382. $this->id = $parentId . '/' . $this->name;
  28383. }
  28384. }
  28385. private function processPath(): void
  28386. {
  28387. if ($this->parent === null) {
  28388. $this->pathAsArray = [$this];
  28389. $this->pathAsString = $this->name;
  28390. return;
  28391. }
  28392. $this->pathAsArray = $this->parent->pathAsArray();
  28393. $this->pathAsString = $this->parent->pathAsString() . DIRECTORY_SEPARATOR . $this->name;
  28394. $this->pathAsArray[] = $this;
  28395. }
  28396. }
  28397. <?php
  28398. declare (strict_types=1);
  28399. /*
  28400. * This file is part of phpunit/php-code-coverage.
  28401. *
  28402. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28403. *
  28404. * For the full copyright and license information, please view the LICENSE
  28405. * file that was distributed with this source code.
  28406. */
  28407. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  28408. use const DIRECTORY_SEPARATOR;
  28409. use function array_shift;
  28410. use function basename;
  28411. use function count;
  28412. use function dirname;
  28413. use function explode;
  28414. use function implode;
  28415. use function is_file;
  28416. use function str_ends_with;
  28417. use function str_replace;
  28418. use function str_starts_with;
  28419. use function substr;
  28420. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  28421. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData;
  28422. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
  28423. /**
  28424. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  28425. *
  28426. * @psalm-import-type TestType from \SebastianBergmann\CodeCoverage\CodeCoverage
  28427. */
  28428. final class Builder
  28429. {
  28430. private readonly FileAnalyser $analyser;
  28431. public function __construct(FileAnalyser $analyser)
  28432. {
  28433. $this->analyser = $analyser;
  28434. }
  28435. public function build(CodeCoverage $coverage): Directory
  28436. {
  28437. $data = clone $coverage->getData();
  28438. // clone because path munging is destructive to the original data
  28439. $commonPath = $this->reducePaths($data);
  28440. $root = new Directory($commonPath, null);
  28441. $this->addItems($root, $this->buildDirectoryStructure($data), $coverage->getTests());
  28442. return $root;
  28443. }
  28444. /**
  28445. * @psalm-param array<string, TestType> $tests
  28446. */
  28447. private function addItems(Directory $root, array $items, array $tests): void
  28448. {
  28449. foreach ($items as $key => $value) {
  28450. $key = (string) $key;
  28451. if (str_ends_with($key, '/f')) {
  28452. $key = substr($key, 0, -2);
  28453. $filename = $root->pathAsString() . DIRECTORY_SEPARATOR . $key;
  28454. if (is_file($filename)) {
  28455. $root->addFile(new File($key, $root, $value['lineCoverage'], $value['functionCoverage'], $tests, $this->analyser->classesIn($filename), $this->analyser->traitsIn($filename), $this->analyser->functionsIn($filename), $this->analyser->linesOfCodeFor($filename)));
  28456. }
  28457. } else {
  28458. $child = $root->addDirectory($key);
  28459. $this->addItems($child, $value, $tests);
  28460. }
  28461. }
  28462. }
  28463. /**
  28464. * Builds an array representation of the directory structure.
  28465. *
  28466. * For instance,
  28467. *
  28468. * <code>
  28469. * Array
  28470. * (
  28471. * [Money.php] => Array
  28472. * (
  28473. * ...
  28474. * )
  28475. *
  28476. * [MoneyBag.php] => Array
  28477. * (
  28478. * ...
  28479. * )
  28480. * )
  28481. * </code>
  28482. *
  28483. * is transformed into
  28484. *
  28485. * <code>
  28486. * Array
  28487. * (
  28488. * [.] => Array
  28489. * (
  28490. * [Money.php] => Array
  28491. * (
  28492. * ...
  28493. * )
  28494. *
  28495. * [MoneyBag.php] => Array
  28496. * (
  28497. * ...
  28498. * )
  28499. * )
  28500. * )
  28501. * </code>
  28502. *
  28503. * @psalm-return array<string, array<string, array{lineCoverage: array<int, int>, functionCoverage: array<string, array<int, int>>}>>
  28504. */
  28505. private function buildDirectoryStructure(ProcessedCodeCoverageData $data): array
  28506. {
  28507. $result = [];
  28508. foreach ($data->coveredFiles() as $originalPath) {
  28509. $path = explode(DIRECTORY_SEPARATOR, $originalPath);
  28510. $pointer =& $result;
  28511. $max = count($path);
  28512. for ($i = 0; $i < $max; $i++) {
  28513. $type = '';
  28514. if ($i === $max - 1) {
  28515. $type = '/f';
  28516. }
  28517. $pointer =& $pointer[$path[$i] . $type];
  28518. }
  28519. $pointer = ['lineCoverage' => $data->lineCoverage()[$originalPath] ?? [], 'functionCoverage' => $data->functionCoverage()[$originalPath] ?? []];
  28520. }
  28521. return $result;
  28522. }
  28523. /**
  28524. * Reduces the paths by cutting the longest common start path.
  28525. *
  28526. * For instance,
  28527. *
  28528. * <code>
  28529. * Array
  28530. * (
  28531. * [/home/sb/Money/Money.php] => Array
  28532. * (
  28533. * ...
  28534. * )
  28535. *
  28536. * [/home/sb/Money/MoneyBag.php] => Array
  28537. * (
  28538. * ...
  28539. * )
  28540. * )
  28541. * </code>
  28542. *
  28543. * is reduced to
  28544. *
  28545. * <code>
  28546. * Array
  28547. * (
  28548. * [Money.php] => Array
  28549. * (
  28550. * ...
  28551. * )
  28552. *
  28553. * [MoneyBag.php] => Array
  28554. * (
  28555. * ...
  28556. * )
  28557. * )
  28558. * </code>
  28559. */
  28560. private function reducePaths(ProcessedCodeCoverageData $coverage): string
  28561. {
  28562. if (empty($coverage->coveredFiles())) {
  28563. return '.';
  28564. }
  28565. $commonPath = '';
  28566. $paths = $coverage->coveredFiles();
  28567. if (count($paths) === 1) {
  28568. $commonPath = dirname($paths[0]) . DIRECTORY_SEPARATOR;
  28569. $coverage->renameFile($paths[0], basename($paths[0]));
  28570. return $commonPath;
  28571. }
  28572. $max = count($paths);
  28573. for ($i = 0; $i < $max; $i++) {
  28574. // strip phar:// prefixes
  28575. if (str_starts_with($paths[$i], 'phar://')) {
  28576. $paths[$i] = substr($paths[$i], 7);
  28577. $paths[$i] = str_replace('/', DIRECTORY_SEPARATOR, $paths[$i]);
  28578. }
  28579. $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
  28580. if (empty($paths[$i][0])) {
  28581. $paths[$i][0] = DIRECTORY_SEPARATOR;
  28582. }
  28583. }
  28584. $done = \false;
  28585. $max = count($paths);
  28586. while (!$done) {
  28587. for ($i = 0; $i < $max - 1; $i++) {
  28588. if (!isset($paths[$i][0]) || !isset($paths[$i + 1][0]) || $paths[$i][0] !== $paths[$i + 1][0]) {
  28589. $done = \true;
  28590. break;
  28591. }
  28592. }
  28593. if (!$done) {
  28594. $commonPath .= $paths[0][0];
  28595. if ($paths[0][0] !== DIRECTORY_SEPARATOR) {
  28596. $commonPath .= DIRECTORY_SEPARATOR;
  28597. }
  28598. for ($i = 0; $i < $max; $i++) {
  28599. array_shift($paths[$i]);
  28600. }
  28601. }
  28602. }
  28603. $original = $coverage->coveredFiles();
  28604. $max = count($original);
  28605. for ($i = 0; $i < $max; $i++) {
  28606. $coverage->renameFile($original[$i], implode(DIRECTORY_SEPARATOR, $paths[$i]));
  28607. }
  28608. return substr($commonPath, 0, -1);
  28609. }
  28610. }
  28611. <?php
  28612. declare (strict_types=1);
  28613. /*
  28614. * This file is part of phpunit/php-code-coverage.
  28615. *
  28616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28617. *
  28618. * For the full copyright and license information, please view the LICENSE
  28619. * file that was distributed with this source code.
  28620. */
  28621. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  28622. use function sprintf;
  28623. /**
  28624. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  28625. */
  28626. final class CrapIndex
  28627. {
  28628. private readonly int $cyclomaticComplexity;
  28629. private readonly float $codeCoverage;
  28630. public function __construct(int $cyclomaticComplexity, float $codeCoverage)
  28631. {
  28632. $this->cyclomaticComplexity = $cyclomaticComplexity;
  28633. $this->codeCoverage = $codeCoverage;
  28634. }
  28635. public function asString(): string
  28636. {
  28637. if ($this->codeCoverage === 0.0) {
  28638. return (string) ($this->cyclomaticComplexity ** 2 + $this->cyclomaticComplexity);
  28639. }
  28640. if ($this->codeCoverage >= 95) {
  28641. return (string) $this->cyclomaticComplexity;
  28642. }
  28643. return sprintf('%01.2F', $this->cyclomaticComplexity ** 2 * (1 - $this->codeCoverage / 100) ** 3 + $this->cyclomaticComplexity);
  28644. }
  28645. }
  28646. <?php
  28647. declare (strict_types=1);
  28648. /*
  28649. * This file is part of phpunit/php-code-coverage.
  28650. *
  28651. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28652. *
  28653. * For the full copyright and license information, please view the LICENSE
  28654. * file that was distributed with this source code.
  28655. */
  28656. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  28657. use function array_merge;
  28658. use function count;
  28659. use IteratorAggregate;
  28660. use RecursiveIteratorIterator;
  28661. /**
  28662. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  28663. *
  28664. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  28665. */
  28666. final class Directory extends AbstractNode implements IteratorAggregate
  28667. {
  28668. /**
  28669. * @var list<AbstractNode>
  28670. */
  28671. private array $children = [];
  28672. /**
  28673. * @var list<Directory>
  28674. */
  28675. private array $directories = [];
  28676. /**
  28677. * @var list<File>
  28678. */
  28679. private array $files = [];
  28680. private ?array $classes = null;
  28681. private ?array $traits = null;
  28682. private ?array $functions = null;
  28683. /**
  28684. * @psalm-var null|LinesOfCodeType
  28685. */
  28686. private ?array $linesOfCode = null;
  28687. private int $numFiles = -1;
  28688. private int $numExecutableLines = -1;
  28689. private int $numExecutedLines = -1;
  28690. private int $numExecutableBranches = -1;
  28691. private int $numExecutedBranches = -1;
  28692. private int $numExecutablePaths = -1;
  28693. private int $numExecutedPaths = -1;
  28694. private int $numClasses = -1;
  28695. private int $numTestedClasses = -1;
  28696. private int $numTraits = -1;
  28697. private int $numTestedTraits = -1;
  28698. private int $numMethods = -1;
  28699. private int $numTestedMethods = -1;
  28700. private int $numFunctions = -1;
  28701. private int $numTestedFunctions = -1;
  28702. public function count(): int
  28703. {
  28704. if ($this->numFiles === -1) {
  28705. $this->numFiles = 0;
  28706. foreach ($this->children as $child) {
  28707. $this->numFiles += count($child);
  28708. }
  28709. }
  28710. return $this->numFiles;
  28711. }
  28712. public function getIterator(): RecursiveIteratorIterator
  28713. {
  28714. return new RecursiveIteratorIterator(new Iterator($this), RecursiveIteratorIterator::SELF_FIRST);
  28715. }
  28716. public function addDirectory(string $name): self
  28717. {
  28718. $directory = new self($name, $this);
  28719. $this->children[] = $directory;
  28720. $this->directories[] =& $this->children[count($this->children) - 1];
  28721. return $directory;
  28722. }
  28723. public function addFile(File $file): void
  28724. {
  28725. $this->children[] = $file;
  28726. $this->files[] =& $this->children[count($this->children) - 1];
  28727. $this->numExecutableLines = -1;
  28728. $this->numExecutedLines = -1;
  28729. }
  28730. public function directories(): array
  28731. {
  28732. return $this->directories;
  28733. }
  28734. public function files(): array
  28735. {
  28736. return $this->files;
  28737. }
  28738. public function children(): array
  28739. {
  28740. return $this->children;
  28741. }
  28742. public function classes(): array
  28743. {
  28744. if ($this->classes === null) {
  28745. $this->classes = [];
  28746. foreach ($this->children as $child) {
  28747. $this->classes = array_merge($this->classes, $child->classes());
  28748. }
  28749. }
  28750. return $this->classes;
  28751. }
  28752. public function traits(): array
  28753. {
  28754. if ($this->traits === null) {
  28755. $this->traits = [];
  28756. foreach ($this->children as $child) {
  28757. $this->traits = array_merge($this->traits, $child->traits());
  28758. }
  28759. }
  28760. return $this->traits;
  28761. }
  28762. public function functions(): array
  28763. {
  28764. if ($this->functions === null) {
  28765. $this->functions = [];
  28766. foreach ($this->children as $child) {
  28767. $this->functions = array_merge($this->functions, $child->functions());
  28768. }
  28769. }
  28770. return $this->functions;
  28771. }
  28772. /**
  28773. * @psalm-return LinesOfCodeType
  28774. */
  28775. public function linesOfCode(): array
  28776. {
  28777. if ($this->linesOfCode === null) {
  28778. $this->linesOfCode = ['linesOfCode' => 0, 'commentLinesOfCode' => 0, 'nonCommentLinesOfCode' => 0];
  28779. foreach ($this->children as $child) {
  28780. $childLinesOfCode = $child->linesOfCode();
  28781. $this->linesOfCode['linesOfCode'] += $childLinesOfCode['linesOfCode'];
  28782. $this->linesOfCode['commentLinesOfCode'] += $childLinesOfCode['commentLinesOfCode'];
  28783. $this->linesOfCode['nonCommentLinesOfCode'] += $childLinesOfCode['nonCommentLinesOfCode'];
  28784. }
  28785. }
  28786. return $this->linesOfCode;
  28787. }
  28788. public function numberOfExecutableLines(): int
  28789. {
  28790. if ($this->numExecutableLines === -1) {
  28791. $this->numExecutableLines = 0;
  28792. foreach ($this->children as $child) {
  28793. $this->numExecutableLines += $child->numberOfExecutableLines();
  28794. }
  28795. }
  28796. return $this->numExecutableLines;
  28797. }
  28798. public function numberOfExecutedLines(): int
  28799. {
  28800. if ($this->numExecutedLines === -1) {
  28801. $this->numExecutedLines = 0;
  28802. foreach ($this->children as $child) {
  28803. $this->numExecutedLines += $child->numberOfExecutedLines();
  28804. }
  28805. }
  28806. return $this->numExecutedLines;
  28807. }
  28808. public function numberOfExecutableBranches(): int
  28809. {
  28810. if ($this->numExecutableBranches === -1) {
  28811. $this->numExecutableBranches = 0;
  28812. foreach ($this->children as $child) {
  28813. $this->numExecutableBranches += $child->numberOfExecutableBranches();
  28814. }
  28815. }
  28816. return $this->numExecutableBranches;
  28817. }
  28818. public function numberOfExecutedBranches(): int
  28819. {
  28820. if ($this->numExecutedBranches === -1) {
  28821. $this->numExecutedBranches = 0;
  28822. foreach ($this->children as $child) {
  28823. $this->numExecutedBranches += $child->numberOfExecutedBranches();
  28824. }
  28825. }
  28826. return $this->numExecutedBranches;
  28827. }
  28828. public function numberOfExecutablePaths(): int
  28829. {
  28830. if ($this->numExecutablePaths === -1) {
  28831. $this->numExecutablePaths = 0;
  28832. foreach ($this->children as $child) {
  28833. $this->numExecutablePaths += $child->numberOfExecutablePaths();
  28834. }
  28835. }
  28836. return $this->numExecutablePaths;
  28837. }
  28838. public function numberOfExecutedPaths(): int
  28839. {
  28840. if ($this->numExecutedPaths === -1) {
  28841. $this->numExecutedPaths = 0;
  28842. foreach ($this->children as $child) {
  28843. $this->numExecutedPaths += $child->numberOfExecutedPaths();
  28844. }
  28845. }
  28846. return $this->numExecutedPaths;
  28847. }
  28848. public function numberOfClasses(): int
  28849. {
  28850. if ($this->numClasses === -1) {
  28851. $this->numClasses = 0;
  28852. foreach ($this->children as $child) {
  28853. $this->numClasses += $child->numberOfClasses();
  28854. }
  28855. }
  28856. return $this->numClasses;
  28857. }
  28858. public function numberOfTestedClasses(): int
  28859. {
  28860. if ($this->numTestedClasses === -1) {
  28861. $this->numTestedClasses = 0;
  28862. foreach ($this->children as $child) {
  28863. $this->numTestedClasses += $child->numberOfTestedClasses();
  28864. }
  28865. }
  28866. return $this->numTestedClasses;
  28867. }
  28868. public function numberOfTraits(): int
  28869. {
  28870. if ($this->numTraits === -1) {
  28871. $this->numTraits = 0;
  28872. foreach ($this->children as $child) {
  28873. $this->numTraits += $child->numberOfTraits();
  28874. }
  28875. }
  28876. return $this->numTraits;
  28877. }
  28878. public function numberOfTestedTraits(): int
  28879. {
  28880. if ($this->numTestedTraits === -1) {
  28881. $this->numTestedTraits = 0;
  28882. foreach ($this->children as $child) {
  28883. $this->numTestedTraits += $child->numberOfTestedTraits();
  28884. }
  28885. }
  28886. return $this->numTestedTraits;
  28887. }
  28888. public function numberOfMethods(): int
  28889. {
  28890. if ($this->numMethods === -1) {
  28891. $this->numMethods = 0;
  28892. foreach ($this->children as $child) {
  28893. $this->numMethods += $child->numberOfMethods();
  28894. }
  28895. }
  28896. return $this->numMethods;
  28897. }
  28898. public function numberOfTestedMethods(): int
  28899. {
  28900. if ($this->numTestedMethods === -1) {
  28901. $this->numTestedMethods = 0;
  28902. foreach ($this->children as $child) {
  28903. $this->numTestedMethods += $child->numberOfTestedMethods();
  28904. }
  28905. }
  28906. return $this->numTestedMethods;
  28907. }
  28908. public function numberOfFunctions(): int
  28909. {
  28910. if ($this->numFunctions === -1) {
  28911. $this->numFunctions = 0;
  28912. foreach ($this->children as $child) {
  28913. $this->numFunctions += $child->numberOfFunctions();
  28914. }
  28915. }
  28916. return $this->numFunctions;
  28917. }
  28918. public function numberOfTestedFunctions(): int
  28919. {
  28920. if ($this->numTestedFunctions === -1) {
  28921. $this->numTestedFunctions = 0;
  28922. foreach ($this->children as $child) {
  28923. $this->numTestedFunctions += $child->numberOfTestedFunctions();
  28924. }
  28925. }
  28926. return $this->numTestedFunctions;
  28927. }
  28928. }
  28929. <?php
  28930. declare (strict_types=1);
  28931. /*
  28932. * This file is part of phpunit/php-code-coverage.
  28933. *
  28934. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28935. *
  28936. * For the full copyright and license information, please view the LICENSE
  28937. * file that was distributed with this source code.
  28938. */
  28939. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  28940. use function array_filter;
  28941. use function count;
  28942. use function range;
  28943. /**
  28944. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  28945. *
  28946. * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  28947. * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  28948. * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  28949. * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  28950. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  28951. * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  28952. *
  28953. * @psalm-type ProcessedFunctionType = array{
  28954. * functionName: string,
  28955. * namespace: string,
  28956. * signature: string,
  28957. * startLine: int,
  28958. * endLine: int,
  28959. * executableLines: int,
  28960. * executedLines: int,
  28961. * executableBranches: int,
  28962. * executedBranches: int,
  28963. * executablePaths: int,
  28964. * executedPaths: int,
  28965. * ccn: int,
  28966. * coverage: int|float,
  28967. * crap: int|string,
  28968. * link: string
  28969. * }
  28970. * @psalm-type ProcessedMethodType = array{
  28971. * methodName: string,
  28972. * visibility: string,
  28973. * signature: string,
  28974. * startLine: int,
  28975. * endLine: int,
  28976. * executableLines: int,
  28977. * executedLines: int,
  28978. * executableBranches: int,
  28979. * executedBranches: int,
  28980. * executablePaths: int,
  28981. * executedPaths: int,
  28982. * ccn: int,
  28983. * coverage: float|int,
  28984. * crap: int|string,
  28985. * link: string
  28986. * }
  28987. * @psalm-type ProcessedClassType = array{
  28988. * className: string,
  28989. * namespace: string,
  28990. * methods: array<string, ProcessedMethodType>,
  28991. * startLine: int,
  28992. * executableLines: int,
  28993. * executedLines: int,
  28994. * executableBranches: int,
  28995. * executedBranches: int,
  28996. * executablePaths: int,
  28997. * executedPaths: int,
  28998. * ccn: int,
  28999. * coverage: int|float,
  29000. * crap: int|string,
  29001. * link: string
  29002. * }
  29003. * @psalm-type ProcessedTraitType = array{
  29004. * traitName: string,
  29005. * namespace: string,
  29006. * methods: array<string, ProcessedMethodType>,
  29007. * startLine: int,
  29008. * executableLines: int,
  29009. * executedLines: int,
  29010. * executableBranches: int,
  29011. * executedBranches: int,
  29012. * executablePaths: int,
  29013. * executedPaths: int,
  29014. * ccn: int,
  29015. * coverage: float|int,
  29016. * crap: int|string,
  29017. * link: string
  29018. * }
  29019. */
  29020. final class File extends AbstractNode
  29021. {
  29022. /**
  29023. * @psalm-var array<int, ?list<non-empty-string>>
  29024. */
  29025. private array $lineCoverageData;
  29026. private array $functionCoverageData;
  29027. private readonly array $testData;
  29028. private int $numExecutableLines = 0;
  29029. private int $numExecutedLines = 0;
  29030. private int $numExecutableBranches = 0;
  29031. private int $numExecutedBranches = 0;
  29032. private int $numExecutablePaths = 0;
  29033. private int $numExecutedPaths = 0;
  29034. /**
  29035. * @psalm-var array<string, ProcessedClassType>
  29036. */
  29037. private array $classes = [];
  29038. /**
  29039. * @psalm-var array<string, ProcessedTraitType>
  29040. */
  29041. private array $traits = [];
  29042. /**
  29043. * @psalm-var array<string, ProcessedFunctionType>
  29044. */
  29045. private array $functions = [];
  29046. /**
  29047. * @psalm-var LinesOfCodeType
  29048. */
  29049. private readonly array $linesOfCode;
  29050. private ?int $numClasses = null;
  29051. private int $numTestedClasses = 0;
  29052. private ?int $numTraits = null;
  29053. private int $numTestedTraits = 0;
  29054. private ?int $numMethods = null;
  29055. private ?int $numTestedMethods = null;
  29056. private ?int $numTestedFunctions = null;
  29057. /**
  29058. * @var array<int, array|array{0: CodeUnitClassType, 1: string}|array{0: CodeUnitFunctionType}|array{0: CodeUnitTraitType, 1: string}>
  29059. */
  29060. private array $codeUnitsByLine = [];
  29061. /**
  29062. * @psalm-param array<int, ?list<non-empty-string>> $lineCoverageData
  29063. * @psalm-param LinesOfCodeType $linesOfCode
  29064. * @psalm-param array<string, CodeUnitClassType> $classes
  29065. * @psalm-param array<string, CodeUnitTraitType> $traits
  29066. * @psalm-param array<string, CodeUnitFunctionType> $functions
  29067. */
  29068. public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, array $linesOfCode)
  29069. {
  29070. parent::__construct($name, $parent);
  29071. $this->lineCoverageData = $lineCoverageData;
  29072. $this->functionCoverageData = $functionCoverageData;
  29073. $this->testData = $testData;
  29074. $this->linesOfCode = $linesOfCode;
  29075. $this->calculateStatistics($classes, $traits, $functions);
  29076. }
  29077. public function count(): int
  29078. {
  29079. return 1;
  29080. }
  29081. /**
  29082. * @psalm-return array<int, ?list<non-empty-string>>
  29083. */
  29084. public function lineCoverageData(): array
  29085. {
  29086. return $this->lineCoverageData;
  29087. }
  29088. public function functionCoverageData(): array
  29089. {
  29090. return $this->functionCoverageData;
  29091. }
  29092. public function testData(): array
  29093. {
  29094. return $this->testData;
  29095. }
  29096. public function classes(): array
  29097. {
  29098. return $this->classes;
  29099. }
  29100. public function traits(): array
  29101. {
  29102. return $this->traits;
  29103. }
  29104. public function functions(): array
  29105. {
  29106. return $this->functions;
  29107. }
  29108. public function linesOfCode(): array
  29109. {
  29110. return $this->linesOfCode;
  29111. }
  29112. public function numberOfExecutableLines(): int
  29113. {
  29114. return $this->numExecutableLines;
  29115. }
  29116. public function numberOfExecutedLines(): int
  29117. {
  29118. return $this->numExecutedLines;
  29119. }
  29120. public function numberOfExecutableBranches(): int
  29121. {
  29122. return $this->numExecutableBranches;
  29123. }
  29124. public function numberOfExecutedBranches(): int
  29125. {
  29126. return $this->numExecutedBranches;
  29127. }
  29128. public function numberOfExecutablePaths(): int
  29129. {
  29130. return $this->numExecutablePaths;
  29131. }
  29132. public function numberOfExecutedPaths(): int
  29133. {
  29134. return $this->numExecutedPaths;
  29135. }
  29136. public function numberOfClasses(): int
  29137. {
  29138. if ($this->numClasses === null) {
  29139. $this->numClasses = 0;
  29140. foreach ($this->classes as $class) {
  29141. foreach ($class['methods'] as $method) {
  29142. if ($method['executableLines'] > 0) {
  29143. $this->numClasses++;
  29144. continue 2;
  29145. }
  29146. }
  29147. }
  29148. }
  29149. return $this->numClasses;
  29150. }
  29151. public function numberOfTestedClasses(): int
  29152. {
  29153. return $this->numTestedClasses;
  29154. }
  29155. public function numberOfTraits(): int
  29156. {
  29157. if ($this->numTraits === null) {
  29158. $this->numTraits = 0;
  29159. foreach ($this->traits as $trait) {
  29160. foreach ($trait['methods'] as $method) {
  29161. if ($method['executableLines'] > 0) {
  29162. $this->numTraits++;
  29163. continue 2;
  29164. }
  29165. }
  29166. }
  29167. }
  29168. return $this->numTraits;
  29169. }
  29170. public function numberOfTestedTraits(): int
  29171. {
  29172. return $this->numTestedTraits;
  29173. }
  29174. public function numberOfMethods(): int
  29175. {
  29176. if ($this->numMethods === null) {
  29177. $this->numMethods = 0;
  29178. foreach ($this->classes as $class) {
  29179. foreach ($class['methods'] as $method) {
  29180. if ($method['executableLines'] > 0) {
  29181. $this->numMethods++;
  29182. }
  29183. }
  29184. }
  29185. foreach ($this->traits as $trait) {
  29186. foreach ($trait['methods'] as $method) {
  29187. if ($method['executableLines'] > 0) {
  29188. $this->numMethods++;
  29189. }
  29190. }
  29191. }
  29192. }
  29193. return $this->numMethods;
  29194. }
  29195. public function numberOfTestedMethods(): int
  29196. {
  29197. if ($this->numTestedMethods === null) {
  29198. $this->numTestedMethods = 0;
  29199. foreach ($this->classes as $class) {
  29200. foreach ($class['methods'] as $method) {
  29201. if ($method['executableLines'] > 0 && $method['coverage'] === 100) {
  29202. $this->numTestedMethods++;
  29203. }
  29204. }
  29205. }
  29206. foreach ($this->traits as $trait) {
  29207. foreach ($trait['methods'] as $method) {
  29208. if ($method['executableLines'] > 0 && $method['coverage'] === 100) {
  29209. $this->numTestedMethods++;
  29210. }
  29211. }
  29212. }
  29213. }
  29214. return $this->numTestedMethods;
  29215. }
  29216. public function numberOfFunctions(): int
  29217. {
  29218. return count($this->functions);
  29219. }
  29220. public function numberOfTestedFunctions(): int
  29221. {
  29222. if ($this->numTestedFunctions === null) {
  29223. $this->numTestedFunctions = 0;
  29224. foreach ($this->functions as $function) {
  29225. if ($function['executableLines'] > 0 && $function['coverage'] === 100) {
  29226. $this->numTestedFunctions++;
  29227. }
  29228. }
  29229. }
  29230. return $this->numTestedFunctions;
  29231. }
  29232. /**
  29233. * @psalm-param array<string, CodeUnitClassType> $classes
  29234. * @psalm-param array<string, CodeUnitTraitType> $traits
  29235. * @psalm-param array<string, CodeUnitFunctionType> $functions
  29236. */
  29237. private function calculateStatistics(array $classes, array $traits, array $functions): void
  29238. {
  29239. foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
  29240. $this->codeUnitsByLine[$lineNumber] = [];
  29241. }
  29242. $this->processClasses($classes);
  29243. $this->processTraits($traits);
  29244. $this->processFunctions($functions);
  29245. foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
  29246. if (isset($this->lineCoverageData[$lineNumber])) {
  29247. foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
  29248. $codeUnit['executableLines']++;
  29249. }
  29250. unset($codeUnit);
  29251. $this->numExecutableLines++;
  29252. if (count($this->lineCoverageData[$lineNumber]) > 0) {
  29253. foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
  29254. $codeUnit['executedLines']++;
  29255. }
  29256. unset($codeUnit);
  29257. $this->numExecutedLines++;
  29258. }
  29259. }
  29260. }
  29261. foreach ($this->traits as &$trait) {
  29262. foreach ($trait['methods'] as &$method) {
  29263. $methodLineCoverage = $method['executableLines'] ? $method['executedLines'] / $method['executableLines'] * 100 : 100;
  29264. $methodBranchCoverage = $method['executableBranches'] ? $method['executedBranches'] / $method['executableBranches'] * 100 : 0;
  29265. $methodPathCoverage = $method['executablePaths'] ? $method['executedPaths'] / $method['executablePaths'] * 100 : 0;
  29266. $method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
  29267. $method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
  29268. $trait['ccn'] += $method['ccn'];
  29269. }
  29270. unset($method);
  29271. $traitLineCoverage = $trait['executableLines'] ? $trait['executedLines'] / $trait['executableLines'] * 100 : 100;
  29272. $traitBranchCoverage = $trait['executableBranches'] ? $trait['executedBranches'] / $trait['executableBranches'] * 100 : 0;
  29273. $traitPathCoverage = $trait['executablePaths'] ? $trait['executedPaths'] / $trait['executablePaths'] * 100 : 0;
  29274. $trait['coverage'] = $traitBranchCoverage ?: $traitLineCoverage;
  29275. $trait['crap'] = (new CrapIndex($trait['ccn'], $traitPathCoverage ?: $traitLineCoverage))->asString();
  29276. if ($trait['executableLines'] > 0 && $trait['coverage'] === 100) {
  29277. $this->numTestedClasses++;
  29278. }
  29279. }
  29280. unset($trait);
  29281. foreach ($this->classes as &$class) {
  29282. foreach ($class['methods'] as &$method) {
  29283. $methodLineCoverage = $method['executableLines'] ? $method['executedLines'] / $method['executableLines'] * 100 : 100;
  29284. $methodBranchCoverage = $method['executableBranches'] ? $method['executedBranches'] / $method['executableBranches'] * 100 : 0;
  29285. $methodPathCoverage = $method['executablePaths'] ? $method['executedPaths'] / $method['executablePaths'] * 100 : 0;
  29286. $method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
  29287. $method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
  29288. $class['ccn'] += $method['ccn'];
  29289. }
  29290. unset($method);
  29291. $classLineCoverage = $class['executableLines'] ? $class['executedLines'] / $class['executableLines'] * 100 : 100;
  29292. $classBranchCoverage = $class['executableBranches'] ? $class['executedBranches'] / $class['executableBranches'] * 100 : 0;
  29293. $classPathCoverage = $class['executablePaths'] ? $class['executedPaths'] / $class['executablePaths'] * 100 : 0;
  29294. $class['coverage'] = $classBranchCoverage ?: $classLineCoverage;
  29295. $class['crap'] = (new CrapIndex($class['ccn'], $classPathCoverage ?: $classLineCoverage))->asString();
  29296. if ($class['executableLines'] > 0 && $class['coverage'] === 100) {
  29297. $this->numTestedClasses++;
  29298. }
  29299. }
  29300. unset($class);
  29301. foreach ($this->functions as &$function) {
  29302. $functionLineCoverage = $function['executableLines'] ? $function['executedLines'] / $function['executableLines'] * 100 : 100;
  29303. $functionBranchCoverage = $function['executableBranches'] ? $function['executedBranches'] / $function['executableBranches'] * 100 : 0;
  29304. $functionPathCoverage = $function['executablePaths'] ? $function['executedPaths'] / $function['executablePaths'] * 100 : 0;
  29305. $function['coverage'] = $functionBranchCoverage ?: $functionLineCoverage;
  29306. $function['crap'] = (new CrapIndex($function['ccn'], $functionPathCoverage ?: $functionLineCoverage))->asString();
  29307. if ($function['coverage'] === 100) {
  29308. $this->numTestedFunctions++;
  29309. }
  29310. }
  29311. }
  29312. /**
  29313. * @psalm-param array<string, CodeUnitClassType> $classes
  29314. */
  29315. private function processClasses(array $classes): void
  29316. {
  29317. $link = $this->id() . '.html#';
  29318. foreach ($classes as $className => $class) {
  29319. $this->classes[$className] = ['className' => $className, 'namespace' => $class['namespace'], 'methods' => [], 'startLine' => $class['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'link' => $link . $class['startLine']];
  29320. foreach ($class['methods'] as $methodName => $method) {
  29321. $methodData = $this->newMethod($className, $methodName, $method, $link);
  29322. $this->classes[$className]['methods'][$methodName] = $methodData;
  29323. $this->classes[$className]['executableBranches'] += $methodData['executableBranches'];
  29324. $this->classes[$className]['executedBranches'] += $methodData['executedBranches'];
  29325. $this->classes[$className]['executablePaths'] += $methodData['executablePaths'];
  29326. $this->classes[$className]['executedPaths'] += $methodData['executedPaths'];
  29327. $this->numExecutableBranches += $methodData['executableBranches'];
  29328. $this->numExecutedBranches += $methodData['executedBranches'];
  29329. $this->numExecutablePaths += $methodData['executablePaths'];
  29330. $this->numExecutedPaths += $methodData['executedPaths'];
  29331. foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
  29332. $this->codeUnitsByLine[$lineNumber] = [&$this->classes[$className], &$this->classes[$className]['methods'][$methodName]];
  29333. }
  29334. }
  29335. }
  29336. }
  29337. /**
  29338. * @psalm-param array<string, CodeUnitTraitType> $traits
  29339. */
  29340. private function processTraits(array $traits): void
  29341. {
  29342. $link = $this->id() . '.html#';
  29343. foreach ($traits as $traitName => $trait) {
  29344. $this->traits[$traitName] = ['traitName' => $traitName, 'namespace' => $trait['namespace'], 'methods' => [], 'startLine' => $trait['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'link' => $link . $trait['startLine']];
  29345. foreach ($trait['methods'] as $methodName => $method) {
  29346. $methodData = $this->newMethod($traitName, $methodName, $method, $link);
  29347. $this->traits[$traitName]['methods'][$methodName] = $methodData;
  29348. $this->traits[$traitName]['executableBranches'] += $methodData['executableBranches'];
  29349. $this->traits[$traitName]['executedBranches'] += $methodData['executedBranches'];
  29350. $this->traits[$traitName]['executablePaths'] += $methodData['executablePaths'];
  29351. $this->traits[$traitName]['executedPaths'] += $methodData['executedPaths'];
  29352. $this->numExecutableBranches += $methodData['executableBranches'];
  29353. $this->numExecutedBranches += $methodData['executedBranches'];
  29354. $this->numExecutablePaths += $methodData['executablePaths'];
  29355. $this->numExecutedPaths += $methodData['executedPaths'];
  29356. foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
  29357. $this->codeUnitsByLine[$lineNumber] = [&$this->traits[$traitName], &$this->traits[$traitName]['methods'][$methodName]];
  29358. }
  29359. }
  29360. }
  29361. }
  29362. /**
  29363. * @psalm-param array<string, CodeUnitFunctionType> $functions
  29364. */
  29365. private function processFunctions(array $functions): void
  29366. {
  29367. $link = $this->id() . '.html#';
  29368. foreach ($functions as $functionName => $function) {
  29369. $this->functions[$functionName] = ['functionName' => $functionName, 'namespace' => $function['namespace'], 'signature' => $function['signature'], 'startLine' => $function['startLine'], 'endLine' => $function['endLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => $function['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $function['startLine']];
  29370. foreach (range($function['startLine'], $function['endLine']) as $lineNumber) {
  29371. $this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]];
  29372. }
  29373. if (isset($this->functionCoverageData[$functionName]['branches'])) {
  29374. $this->functions[$functionName]['executableBranches'] = count($this->functionCoverageData[$functionName]['branches']);
  29375. $this->functions[$functionName]['executedBranches'] = count(array_filter($this->functionCoverageData[$functionName]['branches'], static function (array $branch) {
  29376. return (bool) $branch['hit'];
  29377. }));
  29378. }
  29379. if (isset($this->functionCoverageData[$functionName]['paths'])) {
  29380. $this->functions[$functionName]['executablePaths'] = count($this->functionCoverageData[$functionName]['paths']);
  29381. $this->functions[$functionName]['executedPaths'] = count(array_filter($this->functionCoverageData[$functionName]['paths'], static function (array $path) {
  29382. return (bool) $path['hit'];
  29383. }));
  29384. }
  29385. $this->numExecutableBranches += $this->functions[$functionName]['executableBranches'];
  29386. $this->numExecutedBranches += $this->functions[$functionName]['executedBranches'];
  29387. $this->numExecutablePaths += $this->functions[$functionName]['executablePaths'];
  29388. $this->numExecutedPaths += $this->functions[$functionName]['executedPaths'];
  29389. }
  29390. }
  29391. /**
  29392. * @psalm-param CodeUnitMethodType $method
  29393. *
  29394. * @psalm-return ProcessedMethodType
  29395. */
  29396. private function newMethod(string $className, string $methodName, array $method, string $link): array
  29397. {
  29398. $methodData = ['methodName' => $methodName, 'visibility' => $method['visibility'], 'signature' => $method['signature'], 'startLine' => $method['startLine'], 'endLine' => $method['endLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => $method['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $method['startLine']];
  29399. $key = $className . '->' . $methodName;
  29400. if (isset($this->functionCoverageData[$key]['branches'])) {
  29401. $methodData['executableBranches'] = count($this->functionCoverageData[$key]['branches']);
  29402. $methodData['executedBranches'] = count(array_filter($this->functionCoverageData[$key]['branches'], static function (array $branch) {
  29403. return (bool) $branch['hit'];
  29404. }));
  29405. }
  29406. if (isset($this->functionCoverageData[$key]['paths'])) {
  29407. $methodData['executablePaths'] = count($this->functionCoverageData[$key]['paths']);
  29408. $methodData['executedPaths'] = count(array_filter($this->functionCoverageData[$key]['paths'], static function (array $path) {
  29409. return (bool) $path['hit'];
  29410. }));
  29411. }
  29412. return $methodData;
  29413. }
  29414. }
  29415. <?php
  29416. declare (strict_types=1);
  29417. /*
  29418. * This file is part of phpunit/php-code-coverage.
  29419. *
  29420. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29421. *
  29422. * For the full copyright and license information, please view the LICENSE
  29423. * file that was distributed with this source code.
  29424. */
  29425. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
  29426. use function count;
  29427. use RecursiveIterator;
  29428. /**
  29429. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  29430. */
  29431. final class Iterator implements RecursiveIterator
  29432. {
  29433. private int $position;
  29434. /**
  29435. * @var list<AbstractNode>
  29436. */
  29437. private readonly array $nodes;
  29438. public function __construct(Directory $node)
  29439. {
  29440. $this->nodes = $node->children();
  29441. }
  29442. /**
  29443. * Rewinds the Iterator to the first element.
  29444. */
  29445. public function rewind(): void
  29446. {
  29447. $this->position = 0;
  29448. }
  29449. /**
  29450. * Checks if there is a current element after calls to rewind() or next().
  29451. */
  29452. public function valid(): bool
  29453. {
  29454. return $this->position < count($this->nodes);
  29455. }
  29456. /**
  29457. * Returns the key of the current element.
  29458. */
  29459. public function key(): int
  29460. {
  29461. return $this->position;
  29462. }
  29463. /**
  29464. * Returns the current element.
  29465. */
  29466. public function current(): ?AbstractNode
  29467. {
  29468. return $this->valid() ? $this->nodes[$this->position] : null;
  29469. }
  29470. /**
  29471. * Moves forward to next element.
  29472. */
  29473. public function next(): void
  29474. {
  29475. $this->position++;
  29476. }
  29477. /**
  29478. * Returns the sub iterator for the current element.
  29479. */
  29480. public function getChildren(): self
  29481. {
  29482. return new self($this->nodes[$this->position]);
  29483. }
  29484. /**
  29485. * Checks whether the current element has children.
  29486. */
  29487. public function hasChildren(): bool
  29488. {
  29489. return $this->nodes[$this->position] instanceof Directory;
  29490. }
  29491. }
  29492. <?php
  29493. declare (strict_types=1);
  29494. /*
  29495. * This file is part of phpunit/php-code-coverage.
  29496. *
  29497. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29498. *
  29499. * For the full copyright and license information, please view the LICENSE
  29500. * file that was distributed with this source code.
  29501. */
  29502. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  29503. use function count;
  29504. use function dirname;
  29505. use function file_put_contents;
  29506. use function is_string;
  29507. use function ksort;
  29508. use function max;
  29509. use function range;
  29510. use function str_contains;
  29511. use function time;
  29512. use DOMDocument;
  29513. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  29514. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
  29515. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
  29516. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  29517. final class Clover
  29518. {
  29519. /**
  29520. * @throws WriteOperationFailedException
  29521. */
  29522. public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
  29523. {
  29524. $time = (string) time();
  29525. $xmlDocument = new DOMDocument('1.0', 'UTF-8');
  29526. $xmlDocument->formatOutput = \true;
  29527. $xmlCoverage = $xmlDocument->createElement('coverage');
  29528. $xmlCoverage->setAttribute('generated', $time);
  29529. $xmlDocument->appendChild($xmlCoverage);
  29530. $xmlProject = $xmlDocument->createElement('project');
  29531. $xmlProject->setAttribute('timestamp', $time);
  29532. if (is_string($name)) {
  29533. $xmlProject->setAttribute('name', $name);
  29534. }
  29535. $xmlCoverage->appendChild($xmlProject);
  29536. $packages = [];
  29537. $report = $coverage->getReport();
  29538. foreach ($report as $item) {
  29539. if (!$item instanceof File) {
  29540. continue;
  29541. }
  29542. /* @var File $item */
  29543. $xmlFile = $xmlDocument->createElement('file');
  29544. $xmlFile->setAttribute('name', $item->pathAsString());
  29545. $classes = $item->classesAndTraits();
  29546. $coverageData = $item->lineCoverageData();
  29547. $lines = [];
  29548. $namespace = 'global';
  29549. foreach ($classes as $className => $class) {
  29550. $classStatements = 0;
  29551. $coveredClassStatements = 0;
  29552. $coveredMethods = 0;
  29553. $classMethods = 0;
  29554. foreach ($class['methods'] as $methodName => $method) {
  29555. if ($method['executableLines'] == 0) {
  29556. continue;
  29557. }
  29558. $classMethods++;
  29559. $classStatements += $method['executableLines'];
  29560. $coveredClassStatements += $method['executedLines'];
  29561. if ($method['coverage'] == 100) {
  29562. $coveredMethods++;
  29563. }
  29564. $methodCount = 0;
  29565. foreach (range($method['startLine'], $method['endLine']) as $line) {
  29566. if (isset($coverageData[$line])) {
  29567. $methodCount = max($methodCount, count($coverageData[$line]));
  29568. }
  29569. }
  29570. $lines[$method['startLine']] = ['ccn' => $method['ccn'], 'count' => $methodCount, 'crap' => $method['crap'], 'type' => 'method', 'visibility' => $method['visibility'], 'name' => $methodName];
  29571. }
  29572. if (!empty($class['package']['namespace'])) {
  29573. $namespace = $class['package']['namespace'];
  29574. }
  29575. $xmlClass = $xmlDocument->createElement('class');
  29576. $xmlClass->setAttribute('name', $className);
  29577. $xmlClass->setAttribute('namespace', $namespace);
  29578. if (!empty($class['package']['fullPackage'])) {
  29579. $xmlClass->setAttribute('fullPackage', $class['package']['fullPackage']);
  29580. }
  29581. if (!empty($class['package']['category'])) {
  29582. $xmlClass->setAttribute('category', $class['package']['category']);
  29583. }
  29584. if (!empty($class['package']['package'])) {
  29585. $xmlClass->setAttribute('package', $class['package']['package']);
  29586. }
  29587. if (!empty($class['package']['subpackage'])) {
  29588. $xmlClass->setAttribute('subpackage', $class['package']['subpackage']);
  29589. }
  29590. $xmlFile->appendChild($xmlClass);
  29591. $xmlMetrics = $xmlDocument->createElement('metrics');
  29592. $xmlMetrics->setAttribute('complexity', (string) $class['ccn']);
  29593. $xmlMetrics->setAttribute('methods', (string) $classMethods);
  29594. $xmlMetrics->setAttribute('coveredmethods', (string) $coveredMethods);
  29595. $xmlMetrics->setAttribute('conditionals', (string) $class['executableBranches']);
  29596. $xmlMetrics->setAttribute('coveredconditionals', (string) $class['executedBranches']);
  29597. $xmlMetrics->setAttribute('statements', (string) $classStatements);
  29598. $xmlMetrics->setAttribute('coveredstatements', (string) $coveredClassStatements);
  29599. $xmlMetrics->setAttribute('elements', (string) ($classMethods + $classStatements + $class['executableBranches']));
  29600. $xmlMetrics->setAttribute('coveredelements', (string) ($coveredMethods + $coveredClassStatements + $class['executedBranches']));
  29601. $xmlClass->appendChild($xmlMetrics);
  29602. }
  29603. foreach ($coverageData as $line => $data) {
  29604. if ($data === null || isset($lines[$line])) {
  29605. continue;
  29606. }
  29607. $lines[$line] = ['count' => count($data), 'type' => 'stmt'];
  29608. }
  29609. ksort($lines);
  29610. foreach ($lines as $line => $data) {
  29611. $xmlLine = $xmlDocument->createElement('line');
  29612. $xmlLine->setAttribute('num', (string) $line);
  29613. $xmlLine->setAttribute('type', $data['type']);
  29614. if (isset($data['name'])) {
  29615. $xmlLine->setAttribute('name', $data['name']);
  29616. }
  29617. if (isset($data['visibility'])) {
  29618. $xmlLine->setAttribute('visibility', $data['visibility']);
  29619. }
  29620. if (isset($data['ccn'])) {
  29621. $xmlLine->setAttribute('complexity', (string) $data['ccn']);
  29622. }
  29623. if (isset($data['crap'])) {
  29624. $xmlLine->setAttribute('crap', (string) $data['crap']);
  29625. }
  29626. $xmlLine->setAttribute('count', (string) $data['count']);
  29627. $xmlFile->appendChild($xmlLine);
  29628. }
  29629. $linesOfCode = $item->linesOfCode();
  29630. $xmlMetrics = $xmlDocument->createElement('metrics');
  29631. $xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
  29632. $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
  29633. $xmlMetrics->setAttribute('classes', (string) $item->numberOfClassesAndTraits());
  29634. $xmlMetrics->setAttribute('methods', (string) $item->numberOfMethods());
  29635. $xmlMetrics->setAttribute('coveredmethods', (string) $item->numberOfTestedMethods());
  29636. $xmlMetrics->setAttribute('conditionals', (string) $item->numberOfExecutableBranches());
  29637. $xmlMetrics->setAttribute('coveredconditionals', (string) $item->numberOfExecutedBranches());
  29638. $xmlMetrics->setAttribute('statements', (string) $item->numberOfExecutableLines());
  29639. $xmlMetrics->setAttribute('coveredstatements', (string) $item->numberOfExecutedLines());
  29640. $xmlMetrics->setAttribute('elements', (string) ($item->numberOfMethods() + $item->numberOfExecutableLines() + $item->numberOfExecutableBranches()));
  29641. $xmlMetrics->setAttribute('coveredelements', (string) ($item->numberOfTestedMethods() + $item->numberOfExecutedLines() + $item->numberOfExecutedBranches()));
  29642. $xmlFile->appendChild($xmlMetrics);
  29643. if ($namespace === 'global') {
  29644. $xmlProject->appendChild($xmlFile);
  29645. } else {
  29646. if (!isset($packages[$namespace])) {
  29647. $packages[$namespace] = $xmlDocument->createElement('package');
  29648. $packages[$namespace]->setAttribute('name', $namespace);
  29649. $xmlProject->appendChild($packages[$namespace]);
  29650. }
  29651. $packages[$namespace]->appendChild($xmlFile);
  29652. }
  29653. }
  29654. $linesOfCode = $report->linesOfCode();
  29655. $xmlMetrics = $xmlDocument->createElement('metrics');
  29656. $xmlMetrics->setAttribute('files', (string) count($report));
  29657. $xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
  29658. $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
  29659. $xmlMetrics->setAttribute('classes', (string) $report->numberOfClassesAndTraits());
  29660. $xmlMetrics->setAttribute('methods', (string) $report->numberOfMethods());
  29661. $xmlMetrics->setAttribute('coveredmethods', (string) $report->numberOfTestedMethods());
  29662. $xmlMetrics->setAttribute('conditionals', (string) $report->numberOfExecutableBranches());
  29663. $xmlMetrics->setAttribute('coveredconditionals', (string) $report->numberOfExecutedBranches());
  29664. $xmlMetrics->setAttribute('statements', (string) $report->numberOfExecutableLines());
  29665. $xmlMetrics->setAttribute('coveredstatements', (string) $report->numberOfExecutedLines());
  29666. $xmlMetrics->setAttribute('elements', (string) ($report->numberOfMethods() + $report->numberOfExecutableLines() + $report->numberOfExecutableBranches()));
  29667. $xmlMetrics->setAttribute('coveredelements', (string) ($report->numberOfTestedMethods() + $report->numberOfExecutedLines() + $report->numberOfExecutedBranches()));
  29668. $xmlProject->appendChild($xmlMetrics);
  29669. $buffer = $xmlDocument->saveXML();
  29670. if ($target !== null) {
  29671. if (!str_contains($target, '://')) {
  29672. Filesystem::createDirectory(dirname($target));
  29673. }
  29674. if (@file_put_contents($target, $buffer) === \false) {
  29675. throw new WriteOperationFailedException($target);
  29676. }
  29677. }
  29678. return $buffer;
  29679. }
  29680. }
  29681. <?php
  29682. declare (strict_types=1);
  29683. /*
  29684. * This file is part of phpunit/php-code-coverage.
  29685. *
  29686. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29687. *
  29688. * For the full copyright and license information, please view the LICENSE
  29689. * file that was distributed with this source code.
  29690. */
  29691. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  29692. use function basename;
  29693. use function count;
  29694. use function dirname;
  29695. use function file_put_contents;
  29696. use function preg_match;
  29697. use function range;
  29698. use function str_contains;
  29699. use function str_replace;
  29700. use function time;
  29701. use DOMImplementation;
  29702. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  29703. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
  29704. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
  29705. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  29706. final class Cobertura
  29707. {
  29708. /**
  29709. * @throws WriteOperationFailedException
  29710. */
  29711. public function process(CodeCoverage $coverage, ?string $target = null): string
  29712. {
  29713. $time = (string) time();
  29714. $report = $coverage->getReport();
  29715. $implementation = new DOMImplementation();
  29716. $documentType = $implementation->createDocumentType('coverage', '', 'http://cobertura.sourceforge.net/xml/coverage-04.dtd');
  29717. $document = $implementation->createDocument('', '', $documentType);
  29718. $document->xmlVersion = '1.0';
  29719. $document->encoding = 'UTF-8';
  29720. $document->formatOutput = \true;
  29721. $coverageElement = $document->createElement('coverage');
  29722. $linesValid = $report->numberOfExecutableLines();
  29723. $linesCovered = $report->numberOfExecutedLines();
  29724. $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
  29725. $coverageElement->setAttribute('line-rate', (string) $lineRate);
  29726. $branchesValid = $report->numberOfExecutableBranches();
  29727. $branchesCovered = $report->numberOfExecutedBranches();
  29728. $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
  29729. $coverageElement->setAttribute('branch-rate', (string) $branchRate);
  29730. $coverageElement->setAttribute('lines-covered', (string) $report->numberOfExecutedLines());
  29731. $coverageElement->setAttribute('lines-valid', (string) $report->numberOfExecutableLines());
  29732. $coverageElement->setAttribute('branches-covered', (string) $report->numberOfExecutedBranches());
  29733. $coverageElement->setAttribute('branches-valid', (string) $report->numberOfExecutableBranches());
  29734. $coverageElement->setAttribute('complexity', '');
  29735. $coverageElement->setAttribute('version', '0.4');
  29736. $coverageElement->setAttribute('timestamp', $time);
  29737. $document->appendChild($coverageElement);
  29738. $sourcesElement = $document->createElement('sources');
  29739. $coverageElement->appendChild($sourcesElement);
  29740. $sourceElement = $document->createElement('source', $report->pathAsString());
  29741. $sourcesElement->appendChild($sourceElement);
  29742. $packagesElement = $document->createElement('packages');
  29743. $coverageElement->appendChild($packagesElement);
  29744. $complexity = 0;
  29745. foreach ($report as $item) {
  29746. if (!$item instanceof File) {
  29747. continue;
  29748. }
  29749. $packageElement = $document->createElement('package');
  29750. $packageComplexity = 0;
  29751. $packageElement->setAttribute('name', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
  29752. $linesValid = $item->numberOfExecutableLines();
  29753. $linesCovered = $item->numberOfExecutedLines();
  29754. $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
  29755. $packageElement->setAttribute('line-rate', (string) $lineRate);
  29756. $branchesValid = $item->numberOfExecutableBranches();
  29757. $branchesCovered = $item->numberOfExecutedBranches();
  29758. $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
  29759. $packageElement->setAttribute('branch-rate', (string) $branchRate);
  29760. $packageElement->setAttribute('complexity', '');
  29761. $packagesElement->appendChild($packageElement);
  29762. $classesElement = $document->createElement('classes');
  29763. $packageElement->appendChild($classesElement);
  29764. $classes = $item->classesAndTraits();
  29765. $coverageData = $item->lineCoverageData();
  29766. foreach ($classes as $className => $class) {
  29767. $complexity += $class['ccn'];
  29768. $packageComplexity += $class['ccn'];
  29769. if (!empty($class['package']['namespace'])) {
  29770. $className = $class['package']['namespace'] . '\\' . $className;
  29771. }
  29772. $linesValid = $class['executableLines'];
  29773. $linesCovered = $class['executedLines'];
  29774. $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
  29775. $branchesValid = $class['executableBranches'];
  29776. $branchesCovered = $class['executedBranches'];
  29777. $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
  29778. $classElement = $document->createElement('class');
  29779. $classElement->setAttribute('name', $className);
  29780. $classElement->setAttribute('filename', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
  29781. $classElement->setAttribute('line-rate', (string) $lineRate);
  29782. $classElement->setAttribute('branch-rate', (string) $branchRate);
  29783. $classElement->setAttribute('complexity', (string) $class['ccn']);
  29784. $classesElement->appendChild($classElement);
  29785. $methodsElement = $document->createElement('methods');
  29786. $classElement->appendChild($methodsElement);
  29787. $classLinesElement = $document->createElement('lines');
  29788. $classElement->appendChild($classLinesElement);
  29789. foreach ($class['methods'] as $methodName => $method) {
  29790. if ($method['executableLines'] === 0) {
  29791. continue;
  29792. }
  29793. preg_match("/\\((.*?)\\)/", $method['signature'], $signature);
  29794. $linesValid = $method['executableLines'];
  29795. $linesCovered = $method['executedLines'];
  29796. $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
  29797. $branchesValid = $method['executableBranches'];
  29798. $branchesCovered = $method['executedBranches'];
  29799. $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
  29800. $methodElement = $document->createElement('method');
  29801. $methodElement->setAttribute('name', $methodName);
  29802. $methodElement->setAttribute('signature', $signature[1]);
  29803. $methodElement->setAttribute('line-rate', (string) $lineRate);
  29804. $methodElement->setAttribute('branch-rate', (string) $branchRate);
  29805. $methodElement->setAttribute('complexity', (string) $method['ccn']);
  29806. $methodLinesElement = $document->createElement('lines');
  29807. $methodElement->appendChild($methodLinesElement);
  29808. foreach (range($method['startLine'], $method['endLine']) as $line) {
  29809. if (!isset($coverageData[$line])) {
  29810. continue;
  29811. }
  29812. $methodLineElement = $document->createElement('line');
  29813. $methodLineElement->setAttribute('number', (string) $line);
  29814. $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
  29815. $methodLinesElement->appendChild($methodLineElement);
  29816. $classLineElement = $methodLineElement->cloneNode();
  29817. $classLinesElement->appendChild($classLineElement);
  29818. }
  29819. $methodsElement->appendChild($methodElement);
  29820. }
  29821. }
  29822. if ($item->numberOfFunctions() === 0) {
  29823. $packageElement->setAttribute('complexity', (string) $packageComplexity);
  29824. continue;
  29825. }
  29826. $functionsComplexity = 0;
  29827. $functionsLinesValid = 0;
  29828. $functionsLinesCovered = 0;
  29829. $functionsBranchesValid = 0;
  29830. $functionsBranchesCovered = 0;
  29831. $classElement = $document->createElement('class');
  29832. $classElement->setAttribute('name', basename($item->pathAsString()));
  29833. $classElement->setAttribute('filename', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
  29834. $methodsElement = $document->createElement('methods');
  29835. $classElement->appendChild($methodsElement);
  29836. $classLinesElement = $document->createElement('lines');
  29837. $classElement->appendChild($classLinesElement);
  29838. $functions = $item->functions();
  29839. foreach ($functions as $functionName => $function) {
  29840. if ($function['executableLines'] === 0) {
  29841. continue;
  29842. }
  29843. $complexity += $function['ccn'];
  29844. $packageComplexity += $function['ccn'];
  29845. $functionsComplexity += $function['ccn'];
  29846. $linesValid = $function['executableLines'];
  29847. $linesCovered = $function['executedLines'];
  29848. $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
  29849. $functionsLinesValid += $linesValid;
  29850. $functionsLinesCovered += $linesCovered;
  29851. $branchesValid = $function['executableBranches'];
  29852. $branchesCovered = $function['executedBranches'];
  29853. $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
  29854. $functionsBranchesValid += $branchesValid;
  29855. $functionsBranchesCovered += $branchesValid;
  29856. $methodElement = $document->createElement('method');
  29857. $methodElement->setAttribute('name', $functionName);
  29858. $methodElement->setAttribute('signature', $function['signature']);
  29859. $methodElement->setAttribute('line-rate', (string) $lineRate);
  29860. $methodElement->setAttribute('branch-rate', (string) $branchRate);
  29861. $methodElement->setAttribute('complexity', (string) $function['ccn']);
  29862. $methodLinesElement = $document->createElement('lines');
  29863. $methodElement->appendChild($methodLinesElement);
  29864. foreach (range($function['startLine'], $function['endLine']) as $line) {
  29865. if (!isset($coverageData[$line])) {
  29866. continue;
  29867. }
  29868. $methodLineElement = $document->createElement('line');
  29869. $methodLineElement->setAttribute('number', (string) $line);
  29870. $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
  29871. $methodLinesElement->appendChild($methodLineElement);
  29872. $classLineElement = $methodLineElement->cloneNode();
  29873. $classLinesElement->appendChild($classLineElement);
  29874. }
  29875. $methodsElement->appendChild($methodElement);
  29876. }
  29877. $packageElement->setAttribute('complexity', (string) $packageComplexity);
  29878. if ($functionsLinesValid === 0) {
  29879. continue;
  29880. }
  29881. $lineRate = $functionsLinesCovered / $functionsLinesValid;
  29882. $branchRate = $functionsBranchesValid === 0 ? 0 : $functionsBranchesCovered / $functionsBranchesValid;
  29883. $classElement->setAttribute('line-rate', (string) $lineRate);
  29884. $classElement->setAttribute('branch-rate', (string) $branchRate);
  29885. $classElement->setAttribute('complexity', (string) $functionsComplexity);
  29886. $classesElement->appendChild($classElement);
  29887. }
  29888. $coverageElement->setAttribute('complexity', (string) $complexity);
  29889. $buffer = $document->saveXML();
  29890. if ($target !== null) {
  29891. if (!str_contains($target, '://')) {
  29892. Filesystem::createDirectory(dirname($target));
  29893. }
  29894. if (@file_put_contents($target, $buffer) === \false) {
  29895. throw new WriteOperationFailedException($target);
  29896. }
  29897. }
  29898. return $buffer;
  29899. }
  29900. }
  29901. <?php
  29902. declare (strict_types=1);
  29903. /*
  29904. * This file is part of phpunit/php-code-coverage.
  29905. *
  29906. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29907. *
  29908. * For the full copyright and license information, please view the LICENSE
  29909. * file that was distributed with this source code.
  29910. */
  29911. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  29912. use function date;
  29913. use function dirname;
  29914. use function file_put_contents;
  29915. use function htmlspecialchars;
  29916. use function is_string;
  29917. use function round;
  29918. use function str_contains;
  29919. use DOMDocument;
  29920. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  29921. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
  29922. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
  29923. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  29924. final class Crap4j
  29925. {
  29926. private readonly int $threshold;
  29927. public function __construct(int $threshold = 30)
  29928. {
  29929. $this->threshold = $threshold;
  29930. }
  29931. /**
  29932. * @throws WriteOperationFailedException
  29933. */
  29934. public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
  29935. {
  29936. $document = new DOMDocument('1.0', 'UTF-8');
  29937. $document->formatOutput = \true;
  29938. $root = $document->createElement('crap_result');
  29939. $document->appendChild($root);
  29940. $project = $document->createElement('project', is_string($name) ? $name : '');
  29941. $root->appendChild($project);
  29942. $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s')));
  29943. $stats = $document->createElement('stats');
  29944. $methodsNode = $document->createElement('methods');
  29945. $report = $coverage->getReport();
  29946. unset($coverage);
  29947. $fullMethodCount = 0;
  29948. $fullCrapMethodCount = 0;
  29949. $fullCrapLoad = 0;
  29950. $fullCrap = 0;
  29951. foreach ($report as $item) {
  29952. $namespace = 'global';
  29953. if (!$item instanceof File) {
  29954. continue;
  29955. }
  29956. $file = $document->createElement('file');
  29957. $file->setAttribute('name', $item->pathAsString());
  29958. $classes = $item->classesAndTraits();
  29959. foreach ($classes as $className => $class) {
  29960. foreach ($class['methods'] as $methodName => $method) {
  29961. $crapLoad = $this->crapLoad((float) $method['crap'], $method['ccn'], $method['coverage']);
  29962. $fullCrap += $method['crap'];
  29963. $fullCrapLoad += $crapLoad;
  29964. $fullMethodCount++;
  29965. if ($method['crap'] >= $this->threshold) {
  29966. $fullCrapMethodCount++;
  29967. }
  29968. $methodNode = $document->createElement('method');
  29969. if (!empty($class['namespace'])) {
  29970. $namespace = $class['namespace'];
  29971. }
  29972. $methodNode->appendChild($document->createElement('package', $namespace));
  29973. $methodNode->appendChild($document->createElement('className', $className));
  29974. $methodNode->appendChild($document->createElement('methodName', $methodName));
  29975. $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
  29976. $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
  29977. $methodNode->appendChild($document->createElement('crap', (string) $this->roundValue((float) $method['crap'])));
  29978. $methodNode->appendChild($document->createElement('complexity', (string) $method['ccn']));
  29979. $methodNode->appendChild($document->createElement('coverage', (string) $this->roundValue($method['coverage'])));
  29980. $methodNode->appendChild($document->createElement('crapLoad', (string) round($crapLoad)));
  29981. $methodsNode->appendChild($methodNode);
  29982. }
  29983. }
  29984. }
  29985. $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
  29986. $stats->appendChild($document->createElement('methodCount', (string) $fullMethodCount));
  29987. $stats->appendChild($document->createElement('crapMethodCount', (string) $fullCrapMethodCount));
  29988. $stats->appendChild($document->createElement('crapLoad', (string) round($fullCrapLoad)));
  29989. $stats->appendChild($document->createElement('totalCrap', (string) $fullCrap));
  29990. $crapMethodPercent = 0;
  29991. if ($fullMethodCount > 0) {
  29992. $crapMethodPercent = $this->roundValue(100 * $fullCrapMethodCount / $fullMethodCount);
  29993. }
  29994. $stats->appendChild($document->createElement('crapMethodPercent', (string) $crapMethodPercent));
  29995. $root->appendChild($stats);
  29996. $root->appendChild($methodsNode);
  29997. $buffer = $document->saveXML();
  29998. if ($target !== null) {
  29999. if (!str_contains($target, '://')) {
  30000. Filesystem::createDirectory(dirname($target));
  30001. }
  30002. if (@file_put_contents($target, $buffer) === \false) {
  30003. throw new WriteOperationFailedException($target);
  30004. }
  30005. }
  30006. return $buffer;
  30007. }
  30008. private function crapLoad(float $crapValue, int $cyclomaticComplexity, float $coveragePercent): float
  30009. {
  30010. $crapLoad = 0;
  30011. if ($crapValue >= $this->threshold) {
  30012. $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
  30013. $crapLoad += $cyclomaticComplexity / $this->threshold;
  30014. }
  30015. return $crapLoad;
  30016. }
  30017. private function roundValue(float $value): float
  30018. {
  30019. return round($value, 2);
  30020. }
  30021. }
  30022. <?php
  30023. declare (strict_types=1);
  30024. /*
  30025. * This file is part of phpunit/php-code-coverage.
  30026. *
  30027. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30028. *
  30029. * For the full copyright and license information, please view the LICENSE
  30030. * file that was distributed with this source code.
  30031. */
  30032. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30033. /**
  30034. * @psalm-immutable
  30035. */
  30036. final class Colors
  30037. {
  30038. private readonly string $successLow;
  30039. private readonly string $successMedium;
  30040. private readonly string $successHigh;
  30041. private readonly string $warning;
  30042. private readonly string $danger;
  30043. public static function default(): self
  30044. {
  30045. return new self('#dff0d8', '#c3e3b5', '#99cb84', '#fcf8e3', '#f2dede');
  30046. }
  30047. public static function from(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger): self
  30048. {
  30049. return new self($successLow, $successMedium, $successHigh, $warning, $danger);
  30050. }
  30051. private function __construct(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger)
  30052. {
  30053. $this->successLow = $successLow;
  30054. $this->successMedium = $successMedium;
  30055. $this->successHigh = $successHigh;
  30056. $this->warning = $warning;
  30057. $this->danger = $danger;
  30058. }
  30059. public function successLow(): string
  30060. {
  30061. return $this->successLow;
  30062. }
  30063. public function successMedium(): string
  30064. {
  30065. return $this->successMedium;
  30066. }
  30067. public function successHigh(): string
  30068. {
  30069. return $this->successHigh;
  30070. }
  30071. public function warning(): string
  30072. {
  30073. return $this->warning;
  30074. }
  30075. public function danger(): string
  30076. {
  30077. return $this->danger;
  30078. }
  30079. }
  30080. <?php
  30081. declare (strict_types=1);
  30082. /*
  30083. * This file is part of phpunit/php-code-coverage.
  30084. *
  30085. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30086. *
  30087. * For the full copyright and license information, please view the LICENSE
  30088. * file that was distributed with this source code.
  30089. */
  30090. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30091. use function is_file;
  30092. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
  30093. /**
  30094. * @psalm-immutable
  30095. */
  30096. final class CustomCssFile
  30097. {
  30098. private readonly string $path;
  30099. public static function default(): self
  30100. {
  30101. return new self(__DIR__ . '/Renderer/Template/css/custom.css');
  30102. }
  30103. /**
  30104. * @throws InvalidArgumentException
  30105. */
  30106. public static function from(string $path): self
  30107. {
  30108. if (!is_file($path)) {
  30109. throw new InvalidArgumentException('$path does not exist');
  30110. }
  30111. return new self($path);
  30112. }
  30113. private function __construct(string $path)
  30114. {
  30115. $this->path = $path;
  30116. }
  30117. public function path(): string
  30118. {
  30119. return $this->path;
  30120. }
  30121. }
  30122. <?php
  30123. declare (strict_types=1);
  30124. /*
  30125. * This file is part of phpunit/php-code-coverage.
  30126. *
  30127. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30128. *
  30129. * For the full copyright and license information, please view the LICENSE
  30130. * file that was distributed with this source code.
  30131. */
  30132. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30133. use const DIRECTORY_SEPARATOR;
  30134. use function copy;
  30135. use function date;
  30136. use function dirname;
  30137. use function str_ends_with;
  30138. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  30139. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
  30140. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
  30141. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
  30142. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  30143. use PHPUnitPHAR\SebastianBergmann\Template\Exception;
  30144. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  30145. final class Facade
  30146. {
  30147. private readonly string $templatePath;
  30148. private readonly string $generator;
  30149. private readonly Colors $colors;
  30150. private readonly Thresholds $thresholds;
  30151. private readonly CustomCssFile $customCssFile;
  30152. public function __construct(string $generator = '', ?Colors $colors = null, ?Thresholds $thresholds = null, ?CustomCssFile $customCssFile = null)
  30153. {
  30154. $this->generator = $generator;
  30155. $this->colors = $colors ?? Colors::default();
  30156. $this->thresholds = $thresholds ?? Thresholds::default();
  30157. $this->customCssFile = $customCssFile ?? CustomCssFile::default();
  30158. $this->templatePath = __DIR__ . '/Renderer/Template/';
  30159. }
  30160. public function process(CodeCoverage $coverage, string $target): void
  30161. {
  30162. $target = $this->directory($target);
  30163. $report = $coverage->getReport();
  30164. $date = date('D M j G:i:s T Y');
  30165. $dashboard = new Dashboard($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
  30166. $directory = new Directory($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
  30167. $file = new File($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
  30168. $directory->render($report, $target . 'index.html');
  30169. $dashboard->render($report, $target . 'dashboard.html');
  30170. foreach ($report as $node) {
  30171. $id = $node->id();
  30172. if ($node instanceof DirectoryNode) {
  30173. Filesystem::createDirectory($target . $id);
  30174. $directory->render($node, $target . $id . '/index.html');
  30175. $dashboard->render($node, $target . $id . '/dashboard.html');
  30176. } else {
  30177. $dir = dirname($target . $id);
  30178. Filesystem::createDirectory($dir);
  30179. $file->render($node, $target . $id);
  30180. }
  30181. }
  30182. $this->copyFiles($target);
  30183. $this->renderCss($target);
  30184. }
  30185. private function copyFiles(string $target): void
  30186. {
  30187. $dir = $this->directory($target . '_css');
  30188. copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
  30189. copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
  30190. copy($this->customCssFile->path(), $dir . 'custom.css');
  30191. copy($this->templatePath . 'css/octicons.css', $dir . 'octicons.css');
  30192. $dir = $this->directory($target . '_icons');
  30193. copy($this->templatePath . 'icons/file-code.svg', $dir . 'file-code.svg');
  30194. copy($this->templatePath . 'icons/file-directory.svg', $dir . 'file-directory.svg');
  30195. $dir = $this->directory($target . '_js');
  30196. copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
  30197. copy($this->templatePath . 'js/popper.min.js', $dir . 'popper.min.js');
  30198. copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
  30199. copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
  30200. copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
  30201. copy($this->templatePath . 'js/file.js', $dir . 'file.js');
  30202. }
  30203. private function renderCss(string $target): void
  30204. {
  30205. $template = new Template($this->templatePath . 'css/style.css', '{{', '}}');
  30206. $template->setVar(['success-low' => $this->colors->successLow(), 'success-medium' => $this->colors->successMedium(), 'success-high' => $this->colors->successHigh(), 'warning' => $this->colors->warning(), 'danger' => $this->colors->danger()]);
  30207. try {
  30208. $template->renderTo($this->directory($target . '_css') . 'style.css');
  30209. } catch (Exception $e) {
  30210. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30211. }
  30212. }
  30213. private function directory(string $directory): string
  30214. {
  30215. if (!str_ends_with($directory, DIRECTORY_SEPARATOR)) {
  30216. $directory .= DIRECTORY_SEPARATOR;
  30217. }
  30218. Filesystem::createDirectory($directory);
  30219. return $directory;
  30220. }
  30221. }
  30222. <?php
  30223. declare (strict_types=1);
  30224. /*
  30225. * This file is part of phpunit/php-code-coverage.
  30226. *
  30227. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30228. *
  30229. * For the full copyright and license information, please view the LICENSE
  30230. * file that was distributed with this source code.
  30231. */
  30232. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30233. use function array_pop;
  30234. use function count;
  30235. use function sprintf;
  30236. use function str_repeat;
  30237. use function substr_count;
  30238. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
  30239. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
  30240. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
  30241. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
  30242. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Version;
  30243. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  30244. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  30245. /**
  30246. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  30247. */
  30248. abstract class Renderer
  30249. {
  30250. protected string $templatePath;
  30251. protected string $generator;
  30252. protected string $date;
  30253. protected Thresholds $thresholds;
  30254. protected bool $hasBranchCoverage;
  30255. protected string $version;
  30256. public function __construct(string $templatePath, string $generator, string $date, Thresholds $thresholds, bool $hasBranchCoverage)
  30257. {
  30258. $this->templatePath = $templatePath;
  30259. $this->generator = $generator;
  30260. $this->date = $date;
  30261. $this->thresholds = $thresholds;
  30262. $this->version = Version::id();
  30263. $this->hasBranchCoverage = $hasBranchCoverage;
  30264. }
  30265. protected function renderItemTemplate(Template $template, array $data): string
  30266. {
  30267. $numSeparator = '&nbsp;/&nbsp;';
  30268. if (isset($data['numClasses']) && $data['numClasses'] > 0) {
  30269. $classesLevel = $this->colorLevel($data['testedClassesPercent']);
  30270. $classesNumber = $data['numTestedClasses'] . $numSeparator . $data['numClasses'];
  30271. $classesBar = $this->coverageBar($data['testedClassesPercent']);
  30272. } else {
  30273. $classesLevel = '';
  30274. $classesNumber = '0' . $numSeparator . '0';
  30275. $classesBar = '';
  30276. $data['testedClassesPercentAsString'] = 'n/a';
  30277. }
  30278. if ($data['numMethods'] > 0) {
  30279. $methodsLevel = $this->colorLevel($data['testedMethodsPercent']);
  30280. $methodsNumber = $data['numTestedMethods'] . $numSeparator . $data['numMethods'];
  30281. $methodsBar = $this->coverageBar($data['testedMethodsPercent']);
  30282. } else {
  30283. $methodsLevel = '';
  30284. $methodsNumber = '0' . $numSeparator . '0';
  30285. $methodsBar = '';
  30286. $data['testedMethodsPercentAsString'] = 'n/a';
  30287. }
  30288. if ($data['numExecutableLines'] > 0) {
  30289. $linesLevel = $this->colorLevel($data['linesExecutedPercent']);
  30290. $linesNumber = $data['numExecutedLines'] . $numSeparator . $data['numExecutableLines'];
  30291. $linesBar = $this->coverageBar($data['linesExecutedPercent']);
  30292. } else {
  30293. $linesLevel = '';
  30294. $linesNumber = '0' . $numSeparator . '0';
  30295. $linesBar = '';
  30296. $data['linesExecutedPercentAsString'] = 'n/a';
  30297. }
  30298. if ($data['numExecutablePaths'] > 0) {
  30299. $pathsLevel = $this->colorLevel($data['pathsExecutedPercent']);
  30300. $pathsNumber = $data['numExecutedPaths'] . $numSeparator . $data['numExecutablePaths'];
  30301. $pathsBar = $this->coverageBar($data['pathsExecutedPercent']);
  30302. } else {
  30303. $pathsLevel = '';
  30304. $pathsNumber = '0' . $numSeparator . '0';
  30305. $pathsBar = '';
  30306. $data['pathsExecutedPercentAsString'] = 'n/a';
  30307. }
  30308. if ($data['numExecutableBranches'] > 0) {
  30309. $branchesLevel = $this->colorLevel($data['branchesExecutedPercent']);
  30310. $branchesNumber = $data['numExecutedBranches'] . $numSeparator . $data['numExecutableBranches'];
  30311. $branchesBar = $this->coverageBar($data['branchesExecutedPercent']);
  30312. } else {
  30313. $branchesLevel = '';
  30314. $branchesNumber = '0' . $numSeparator . '0';
  30315. $branchesBar = '';
  30316. $data['branchesExecutedPercentAsString'] = 'n/a';
  30317. }
  30318. $template->setVar(['icon' => $data['icon'] ?? '', 'crap' => $data['crap'] ?? '', 'name' => $data['name'], 'lines_bar' => $linesBar, 'lines_executed_percent' => $data['linesExecutedPercentAsString'], 'lines_level' => $linesLevel, 'lines_number' => $linesNumber, 'paths_bar' => $pathsBar, 'paths_executed_percent' => $data['pathsExecutedPercentAsString'], 'paths_level' => $pathsLevel, 'paths_number' => $pathsNumber, 'branches_bar' => $branchesBar, 'branches_executed_percent' => $data['branchesExecutedPercentAsString'], 'branches_level' => $branchesLevel, 'branches_number' => $branchesNumber, 'methods_bar' => $methodsBar, 'methods_tested_percent' => $data['testedMethodsPercentAsString'], 'methods_level' => $methodsLevel, 'methods_number' => $methodsNumber, 'classes_bar' => $classesBar, 'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '', 'classes_level' => $classesLevel, 'classes_number' => $classesNumber]);
  30319. return $template->render();
  30320. }
  30321. protected function setCommonTemplateVariables(Template $template, AbstractNode $node): void
  30322. {
  30323. $template->setVar(['id' => $node->id(), 'full_path' => $node->pathAsString(), 'path_to_root' => $this->pathToRoot($node), 'breadcrumbs' => $this->breadcrumbs($node), 'date' => $this->date, 'version' => $this->version, 'runtime' => $this->runtimeString(), 'generator' => $this->generator, 'low_upper_bound' => $this->thresholds->lowUpperBound(), 'high_lower_bound' => $this->thresholds->highLowerBound()]);
  30324. }
  30325. protected function breadcrumbs(AbstractNode $node): string
  30326. {
  30327. $breadcrumbs = '';
  30328. $path = $node->pathAsArray();
  30329. $pathToRoot = [];
  30330. $max = count($path);
  30331. if ($node instanceof FileNode) {
  30332. $max--;
  30333. }
  30334. for ($i = 0; $i < $max; $i++) {
  30335. $pathToRoot[] = str_repeat('../', $i);
  30336. }
  30337. foreach ($path as $step) {
  30338. if ($step !== $node) {
  30339. $breadcrumbs .= $this->inactiveBreadcrumb($step, array_pop($pathToRoot));
  30340. } else {
  30341. $breadcrumbs .= $this->activeBreadcrumb($step);
  30342. }
  30343. }
  30344. return $breadcrumbs;
  30345. }
  30346. protected function activeBreadcrumb(AbstractNode $node): string
  30347. {
  30348. $buffer = sprintf(' <li class="breadcrumb-item active">%s</li>' . "\n", $node->name());
  30349. if ($node instanceof DirectoryNode) {
  30350. $buffer .= ' <li class="breadcrumb-item">(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
  30351. }
  30352. return $buffer;
  30353. }
  30354. protected function inactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
  30355. {
  30356. return sprintf(' <li class="breadcrumb-item"><a href="%sindex.html">%s</a></li>' . "\n", $pathToRoot, $node->name());
  30357. }
  30358. protected function pathToRoot(AbstractNode $node): string
  30359. {
  30360. $id = $node->id();
  30361. $depth = substr_count($id, '/');
  30362. if ($id !== 'index' && $node instanceof DirectoryNode) {
  30363. $depth++;
  30364. }
  30365. return str_repeat('../', $depth);
  30366. }
  30367. protected function coverageBar(float $percent): string
  30368. {
  30369. $level = $this->colorLevel($percent);
  30370. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'coverage_bar_branch.html' : 'coverage_bar.html');
  30371. $template = new Template($templateName, '{{', '}}');
  30372. $template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
  30373. return $template->render();
  30374. }
  30375. protected function colorLevel(float $percent): string
  30376. {
  30377. if ($percent <= $this->thresholds->lowUpperBound()) {
  30378. return 'danger';
  30379. }
  30380. if ($percent > $this->thresholds->lowUpperBound() && $percent < $this->thresholds->highLowerBound()) {
  30381. return 'warning';
  30382. }
  30383. return 'success';
  30384. }
  30385. private function runtimeString(): string
  30386. {
  30387. $runtime = new Runtime();
  30388. return sprintf('<a href="%s" target="_top">%s %s</a>', $runtime->getVendorUrl(), $runtime->getName(), $runtime->getVersion());
  30389. }
  30390. }
  30391. <?php
  30392. declare (strict_types=1);
  30393. /*
  30394. * This file is part of phpunit/php-code-coverage.
  30395. *
  30396. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30397. *
  30398. * For the full copyright and license information, please view the LICENSE
  30399. * file that was distributed with this source code.
  30400. */
  30401. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30402. use function array_values;
  30403. use function arsort;
  30404. use function asort;
  30405. use function count;
  30406. use function explode;
  30407. use function floor;
  30408. use function json_encode;
  30409. use function sprintf;
  30410. use function str_replace;
  30411. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
  30412. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
  30413. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
  30414. use PHPUnitPHAR\SebastianBergmann\Template\Exception;
  30415. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  30416. /**
  30417. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  30418. */
  30419. final class Dashboard extends Renderer
  30420. {
  30421. public function render(DirectoryNode $node, string $file): void
  30422. {
  30423. $classes = $node->classesAndTraits();
  30424. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'dashboard_branch.html' : 'dashboard.html');
  30425. $template = new Template($templateName, '{{', '}}');
  30426. $this->setCommonTemplateVariables($template, $node);
  30427. $baseLink = $node->id() . '/';
  30428. $complexity = $this->complexity($classes, $baseLink);
  30429. $coverageDistribution = $this->coverageDistribution($classes);
  30430. $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
  30431. $projectRisks = $this->projectRisks($classes, $baseLink);
  30432. $template->setVar(['insufficient_coverage_classes' => $insufficientCoverage['class'], 'insufficient_coverage_methods' => $insufficientCoverage['method'], 'project_risks_classes' => $projectRisks['class'], 'project_risks_methods' => $projectRisks['method'], 'complexity_class' => $complexity['class'], 'complexity_method' => $complexity['method'], 'class_coverage_distribution' => $coverageDistribution['class'], 'method_coverage_distribution' => $coverageDistribution['method']]);
  30433. try {
  30434. $template->renderTo($file);
  30435. } catch (Exception $e) {
  30436. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30437. }
  30438. }
  30439. protected function activeBreadcrumb(AbstractNode $node): string
  30440. {
  30441. return sprintf(' <li class="breadcrumb-item"><a href="index.html">%s</a></li>' . "\n" . ' <li class="breadcrumb-item active">(Dashboard)</li>' . "\n", $node->name());
  30442. }
  30443. /**
  30444. * Returns the data for the Class/Method Complexity charts.
  30445. */
  30446. private function complexity(array $classes, string $baseLink): array
  30447. {
  30448. $result = ['class' => [], 'method' => []];
  30449. foreach ($classes as $className => $class) {
  30450. foreach ($class['methods'] as $methodName => $method) {
  30451. if ($className !== '*') {
  30452. $methodName = $className . '::' . $methodName;
  30453. }
  30454. $result['method'][] = [$method['coverage'], $method['ccn'], sprintf('<a href="%s">%s</a>', str_replace($baseLink, '', $method['link']), $methodName)];
  30455. }
  30456. $result['class'][] = [$class['coverage'], $class['ccn'], sprintf('<a href="%s">%s</a>', str_replace($baseLink, '', $class['link']), $className)];
  30457. }
  30458. return ['class' => json_encode($result['class']), 'method' => json_encode($result['method'])];
  30459. }
  30460. /**
  30461. * Returns the data for the Class / Method Coverage Distribution chart.
  30462. */
  30463. private function coverageDistribution(array $classes): array
  30464. {
  30465. $result = ['class' => ['0%' => 0, '0-10%' => 0, '10-20%' => 0, '20-30%' => 0, '30-40%' => 0, '40-50%' => 0, '50-60%' => 0, '60-70%' => 0, '70-80%' => 0, '80-90%' => 0, '90-100%' => 0, '100%' => 0], 'method' => ['0%' => 0, '0-10%' => 0, '10-20%' => 0, '20-30%' => 0, '30-40%' => 0, '40-50%' => 0, '50-60%' => 0, '60-70%' => 0, '70-80%' => 0, '80-90%' => 0, '90-100%' => 0, '100%' => 0]];
  30466. foreach ($classes as $class) {
  30467. foreach ($class['methods'] as $methodName => $method) {
  30468. if ($method['coverage'] === 0) {
  30469. $result['method']['0%']++;
  30470. } elseif ($method['coverage'] === 100) {
  30471. $result['method']['100%']++;
  30472. } else {
  30473. $key = floor($method['coverage'] / 10) * 10;
  30474. $key = $key . '-' . ($key + 10) . '%';
  30475. $result['method'][$key]++;
  30476. }
  30477. }
  30478. if ($class['coverage'] === 0) {
  30479. $result['class']['0%']++;
  30480. } elseif ($class['coverage'] === 100) {
  30481. $result['class']['100%']++;
  30482. } else {
  30483. $key = floor($class['coverage'] / 10) * 10;
  30484. $key = $key . '-' . ($key + 10) . '%';
  30485. $result['class'][$key]++;
  30486. }
  30487. }
  30488. return ['class' => json_encode(array_values($result['class'])), 'method' => json_encode(array_values($result['method']))];
  30489. }
  30490. /**
  30491. * Returns the classes / methods with insufficient coverage.
  30492. */
  30493. private function insufficientCoverage(array $classes, string $baseLink): array
  30494. {
  30495. $leastTestedClasses = [];
  30496. $leastTestedMethods = [];
  30497. $result = ['class' => '', 'method' => ''];
  30498. foreach ($classes as $className => $class) {
  30499. foreach ($class['methods'] as $methodName => $method) {
  30500. if ($method['coverage'] < $this->thresholds->highLowerBound()) {
  30501. $key = $methodName;
  30502. if ($className !== '*') {
  30503. $key = $className . '::' . $methodName;
  30504. }
  30505. $leastTestedMethods[$key] = $method['coverage'];
  30506. }
  30507. }
  30508. if ($class['coverage'] < $this->thresholds->highLowerBound()) {
  30509. $leastTestedClasses[$className] = $class['coverage'];
  30510. }
  30511. }
  30512. asort($leastTestedClasses);
  30513. asort($leastTestedMethods);
  30514. foreach ($leastTestedClasses as $className => $coverage) {
  30515. $result['class'] .= sprintf(' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n", str_replace($baseLink, '', $classes[$className]['link']), $className, $coverage);
  30516. }
  30517. foreach ($leastTestedMethods as $methodName => $coverage) {
  30518. [$class, $method] = explode('::', $methodName);
  30519. $result['method'] .= sprintf(' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n", str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), $methodName, $method, $coverage);
  30520. }
  30521. return $result;
  30522. }
  30523. /**
  30524. * Returns the project risks according to the CRAP index.
  30525. */
  30526. private function projectRisks(array $classes, string $baseLink): array
  30527. {
  30528. $classRisks = [];
  30529. $methodRisks = [];
  30530. $result = ['class' => '', 'method' => ''];
  30531. foreach ($classes as $className => $class) {
  30532. foreach ($class['methods'] as $methodName => $method) {
  30533. if ($method['coverage'] < $this->thresholds->highLowerBound() && $method['ccn'] > 1) {
  30534. $key = $methodName;
  30535. if ($className !== '*') {
  30536. $key = $className . '::' . $methodName;
  30537. }
  30538. $methodRisks[$key] = $method['crap'];
  30539. }
  30540. }
  30541. if ($class['coverage'] < $this->thresholds->highLowerBound() && $class['ccn'] > count($class['methods'])) {
  30542. $classRisks[$className] = $class['crap'];
  30543. }
  30544. }
  30545. arsort($classRisks);
  30546. arsort($methodRisks);
  30547. foreach ($classRisks as $className => $crap) {
  30548. $result['class'] .= sprintf(' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n", str_replace($baseLink, '', $classes[$className]['link']), $className, $crap);
  30549. }
  30550. foreach ($methodRisks as $methodName => $crap) {
  30551. [$class, $method] = explode('::', $methodName);
  30552. $result['method'] .= sprintf(' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n", str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), $methodName, $method, $crap);
  30553. }
  30554. return $result;
  30555. }
  30556. }
  30557. <?php
  30558. declare (strict_types=1);
  30559. /*
  30560. * This file is part of phpunit/php-code-coverage.
  30561. *
  30562. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30563. *
  30564. * For the full copyright and license information, please view the LICENSE
  30565. * file that was distributed with this source code.
  30566. */
  30567. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30568. use function count;
  30569. use function sprintf;
  30570. use function str_repeat;
  30571. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
  30572. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode as Node;
  30573. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
  30574. use PHPUnitPHAR\SebastianBergmann\Template\Exception;
  30575. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  30576. /**
  30577. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  30578. */
  30579. final class Directory extends Renderer
  30580. {
  30581. public function render(DirectoryNode $node, string $file): void
  30582. {
  30583. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_branch.html' : 'directory.html');
  30584. $template = new Template($templateName, '{{', '}}');
  30585. $this->setCommonTemplateVariables($template, $node);
  30586. $items = $this->renderItem($node, \true);
  30587. foreach ($node->directories() as $item) {
  30588. $items .= $this->renderItem($item);
  30589. }
  30590. foreach ($node->files() as $item) {
  30591. $items .= $this->renderItem($item);
  30592. }
  30593. $template->setVar(['id' => $node->id(), 'items' => $items]);
  30594. try {
  30595. $template->renderTo($file);
  30596. } catch (Exception $e) {
  30597. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30598. }
  30599. }
  30600. private function renderItem(Node $node, bool $total = \false): string
  30601. {
  30602. $data = ['numClasses' => $node->numberOfClassesAndTraits(), 'numTestedClasses' => $node->numberOfTestedClassesAndTraits(), 'numMethods' => $node->numberOfFunctionsAndMethods(), 'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(), 'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(), 'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(), 'numExecutedLines' => $node->numberOfExecutedLines(), 'numExecutableLines' => $node->numberOfExecutableLines(), 'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(), 'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(), 'numExecutedBranches' => $node->numberOfExecutedBranches(), 'numExecutableBranches' => $node->numberOfExecutableBranches(), 'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(), 'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(), 'numExecutedPaths' => $node->numberOfExecutedPaths(), 'numExecutablePaths' => $node->numberOfExecutablePaths(), 'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(), 'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(), 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString()];
  30603. if ($total) {
  30604. $data['name'] = 'Total';
  30605. } else {
  30606. $up = str_repeat('../', count($node->pathAsArray()) - 2);
  30607. $data['icon'] = sprintf('<img src="%s_icons/file-code.svg" class="octicon" />', $up);
  30608. if ($node instanceof DirectoryNode) {
  30609. $data['name'] = sprintf('<a href="%s/index.html">%s</a>', $node->name(), $node->name());
  30610. $data['icon'] = sprintf('<img src="%s_icons/file-directory.svg" class="octicon" />', $up);
  30611. } elseif ($this->hasBranchCoverage) {
  30612. $data['name'] = sprintf('%s <a class="small" href="%s.html">[line]</a> <a class="small" href="%s_branch.html">[branch]</a> <a class="small" href="%s_path.html">[path]</a>', $node->name(), $node->name(), $node->name(), $node->name());
  30613. } else {
  30614. $data['name'] = sprintf('<a href="%s.html">%s</a>', $node->name(), $node->name());
  30615. }
  30616. }
  30617. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_item_branch.html' : 'directory_item.html');
  30618. return $this->renderItemTemplate(new Template($templateName, '{{', '}}'), $data);
  30619. }
  30620. }
  30621. <?php
  30622. declare (strict_types=1);
  30623. /*
  30624. * This file is part of phpunit/php-code-coverage.
  30625. *
  30626. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30627. *
  30628. * For the full copyright and license information, please view the LICENSE
  30629. * file that was distributed with this source code.
  30630. */
  30631. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
  30632. use const ENT_COMPAT;
  30633. use const ENT_HTML401;
  30634. use const ENT_SUBSTITUTE;
  30635. use const T_ABSTRACT;
  30636. use const T_ARRAY;
  30637. use const T_AS;
  30638. use const T_BREAK;
  30639. use const T_CALLABLE;
  30640. use const T_CASE;
  30641. use const T_CATCH;
  30642. use const T_CLASS;
  30643. use const T_CLONE;
  30644. use const T_COMMENT;
  30645. use const T_CONST;
  30646. use const T_CONTINUE;
  30647. use const T_DECLARE;
  30648. use const T_DEFAULT;
  30649. use const T_DO;
  30650. use const T_DOC_COMMENT;
  30651. use const T_ECHO;
  30652. use const T_ELSE;
  30653. use const T_ELSEIF;
  30654. use const T_EMPTY;
  30655. use const T_ENDDECLARE;
  30656. use const T_ENDFOR;
  30657. use const T_ENDFOREACH;
  30658. use const T_ENDIF;
  30659. use const T_ENDSWITCH;
  30660. use const T_ENDWHILE;
  30661. use const T_EVAL;
  30662. use const T_EXIT;
  30663. use const T_EXTENDS;
  30664. use const T_FINAL;
  30665. use const T_FINALLY;
  30666. use const T_FOR;
  30667. use const T_FOREACH;
  30668. use const T_FUNCTION;
  30669. use const T_GLOBAL;
  30670. use const T_GOTO;
  30671. use const T_HALT_COMPILER;
  30672. use const T_IF;
  30673. use const T_IMPLEMENTS;
  30674. use const T_INCLUDE;
  30675. use const T_INCLUDE_ONCE;
  30676. use const T_INLINE_HTML;
  30677. use const T_INSTANCEOF;
  30678. use const T_INSTEADOF;
  30679. use const T_INTERFACE;
  30680. use const T_ISSET;
  30681. use const T_LIST;
  30682. use const T_NAMESPACE;
  30683. use const T_NEW;
  30684. use const T_PRINT;
  30685. use const T_PRIVATE;
  30686. use const T_PROTECTED;
  30687. use const T_PUBLIC;
  30688. use const T_REQUIRE;
  30689. use const T_REQUIRE_ONCE;
  30690. use const T_RETURN;
  30691. use const T_STATIC;
  30692. use const T_SWITCH;
  30693. use const T_THROW;
  30694. use const T_TRAIT;
  30695. use const T_TRY;
  30696. use const T_UNSET;
  30697. use const T_USE;
  30698. use const T_VAR;
  30699. use const T_WHILE;
  30700. use const T_YIELD;
  30701. use const T_YIELD_FROM;
  30702. use function array_key_exists;
  30703. use function array_keys;
  30704. use function array_merge;
  30705. use function array_pop;
  30706. use function array_unique;
  30707. use function count;
  30708. use function explode;
  30709. use function file_get_contents;
  30710. use function htmlspecialchars;
  30711. use function is_string;
  30712. use function ksort;
  30713. use function range;
  30714. use function sort;
  30715. use function sprintf;
  30716. use function str_ends_with;
  30717. use function str_replace;
  30718. use function token_get_all;
  30719. use function trim;
  30720. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
  30721. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
  30722. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
  30723. use PHPUnitPHAR\SebastianBergmann\Template\Exception;
  30724. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  30725. /**
  30726. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  30727. */
  30728. final class File extends Renderer
  30729. {
  30730. /**
  30731. * @psalm-var array<int,true>
  30732. */
  30733. private const KEYWORD_TOKENS = [T_ABSTRACT => \true, T_ARRAY => \true, T_AS => \true, T_BREAK => \true, T_CALLABLE => \true, T_CASE => \true, T_CATCH => \true, T_CLASS => \true, T_CLONE => \true, T_CONST => \true, T_CONTINUE => \true, T_DECLARE => \true, T_DEFAULT => \true, T_DO => \true, T_ECHO => \true, T_ELSE => \true, T_ELSEIF => \true, T_EMPTY => \true, T_ENDDECLARE => \true, T_ENDFOR => \true, T_ENDFOREACH => \true, T_ENDIF => \true, T_ENDSWITCH => \true, T_ENDWHILE => \true, \T_ENUM => \true, T_EVAL => \true, T_EXIT => \true, T_EXTENDS => \true, T_FINAL => \true, T_FINALLY => \true, \T_FN => \true, T_FOR => \true, T_FOREACH => \true, T_FUNCTION => \true, T_GLOBAL => \true, T_GOTO => \true, T_HALT_COMPILER => \true, T_IF => \true, T_IMPLEMENTS => \true, T_INCLUDE => \true, T_INCLUDE_ONCE => \true, T_INSTANCEOF => \true, T_INSTEADOF => \true, T_INTERFACE => \true, T_ISSET => \true, T_LIST => \true, \T_MATCH => \true, T_NAMESPACE => \true, T_NEW => \true, T_PRINT => \true, T_PRIVATE => \true, T_PROTECTED => \true, T_PUBLIC => \true, \T_READONLY => \true, T_REQUIRE => \true, T_REQUIRE_ONCE => \true, T_RETURN => \true, T_STATIC => \true, T_SWITCH => \true, T_THROW => \true, T_TRAIT => \true, T_TRY => \true, T_UNSET => \true, T_USE => \true, T_VAR => \true, T_WHILE => \true, T_YIELD => \true, T_YIELD_FROM => \true];
  30734. private static array $formattedSourceCache = [];
  30735. private int $htmlSpecialCharsFlags = ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE;
  30736. public function render(FileNode $node, string $file): void
  30737. {
  30738. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'file_branch.html' : 'file.html');
  30739. $template = new Template($templateName, '{{', '}}');
  30740. $this->setCommonTemplateVariables($template, $node);
  30741. $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithLineCoverage($node), 'legend' => '<p><span class="legend covered-by-small-tests">Covered by small (and larger) tests</span><span class="legend covered-by-medium-tests">Covered by medium (and large) tests</span><span class="legend covered-by-large-tests">Covered by large tests (and tests of unknown size)</span><span class="legend not-covered">Not covered</span><span class="legend not-coverable">Not coverable</span></p>', 'structure' => '']);
  30742. try {
  30743. $template->renderTo($file . '.html');
  30744. } catch (Exception $e) {
  30745. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30746. }
  30747. if ($this->hasBranchCoverage) {
  30748. $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithBranchCoverage($node), 'legend' => '<p><span class="success"><strong>Fully covered</strong></span><span class="warning"><strong>Partially covered</strong></span><span class="danger"><strong>Not covered</strong></span></p>', 'structure' => $this->renderBranchStructure($node)]);
  30749. try {
  30750. $template->renderTo($file . '_branch.html');
  30751. } catch (Exception $e) {
  30752. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30753. }
  30754. $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithPathCoverage($node), 'legend' => '<p><span class="success"><strong>Fully covered</strong></span><span class="warning"><strong>Partially covered</strong></span><span class="danger"><strong>Not covered</strong></span></p>', 'structure' => $this->renderPathStructure($node)]);
  30755. try {
  30756. $template->renderTo($file . '_path.html');
  30757. } catch (Exception $e) {
  30758. throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
  30759. }
  30760. }
  30761. }
  30762. private function renderItems(FileNode $node): string
  30763. {
  30764. $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'file_item_branch.html' : 'file_item.html');
  30765. $template = new Template($templateName, '{{', '}}');
  30766. $methodTemplateName = $this->templatePath . ($this->hasBranchCoverage ? 'method_item_branch.html' : 'method_item.html');
  30767. $methodItemTemplate = new Template($methodTemplateName, '{{', '}}');
  30768. $items = $this->renderItemTemplate($template, ['name' => 'Total', 'numClasses' => $node->numberOfClassesAndTraits(), 'numTestedClasses' => $node->numberOfTestedClassesAndTraits(), 'numMethods' => $node->numberOfFunctionsAndMethods(), 'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(), 'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(), 'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(), 'numExecutedLines' => $node->numberOfExecutedLines(), 'numExecutableLines' => $node->numberOfExecutableLines(), 'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(), 'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(), 'numExecutedBranches' => $node->numberOfExecutedBranches(), 'numExecutableBranches' => $node->numberOfExecutableBranches(), 'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(), 'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(), 'numExecutedPaths' => $node->numberOfExecutedPaths(), 'numExecutablePaths' => $node->numberOfExecutablePaths(), 'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(), 'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(), 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(), 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>']);
  30769. $items .= $this->renderFunctionItems($node->functions(), $methodItemTemplate);
  30770. $items .= $this->renderTraitOrClassItems($node->traits(), $template, $methodItemTemplate);
  30771. $items .= $this->renderTraitOrClassItems($node->classes(), $template, $methodItemTemplate);
  30772. return $items;
  30773. }
  30774. private function renderTraitOrClassItems(array $items, Template $template, Template $methodItemTemplate): string
  30775. {
  30776. $buffer = '';
  30777. if (empty($items)) {
  30778. return $buffer;
  30779. }
  30780. foreach ($items as $name => $item) {
  30781. $numMethods = 0;
  30782. $numTestedMethods = 0;
  30783. foreach ($item['methods'] as $method) {
  30784. if ($method['executableLines'] > 0) {
  30785. $numMethods++;
  30786. if ($method['executedLines'] === $method['executableLines']) {
  30787. $numTestedMethods++;
  30788. }
  30789. }
  30790. }
  30791. if ($item['executableLines'] > 0) {
  30792. $numClasses = 1;
  30793. $numTestedClasses = $numTestedMethods === $numMethods ? 1 : 0;
  30794. $linesExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines'])->asString();
  30795. $branchesExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches'])->asString();
  30796. $pathsExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths'])->asString();
  30797. } else {
  30798. $numClasses = 0;
  30799. $numTestedClasses = 0;
  30800. $linesExecutedPercentAsString = 'n/a';
  30801. $branchesExecutedPercentAsString = 'n/a';
  30802. $pathsExecutedPercentAsString = 'n/a';
  30803. }
  30804. $testedMethodsPercentage = Percentage::fromFractionAndTotal($numTestedMethods, $numMethods);
  30805. $testedClassesPercentage = Percentage::fromFractionAndTotal($numTestedMethods === $numMethods ? 1 : 0, 1);
  30806. $buffer .= $this->renderItemTemplate($template, ['name' => $this->abbreviateClassName($name), 'numClasses' => $numClasses, 'numTestedClasses' => $numTestedClasses, 'numMethods' => $numMethods, 'numTestedMethods' => $numTestedMethods, 'linesExecutedPercent' => Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines'])->asFloat(), 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, 'numExecutedLines' => $item['executedLines'], 'numExecutableLines' => $item['executableLines'], 'branchesExecutedPercent' => Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches'])->asFloat(), 'branchesExecutedPercentAsString' => $branchesExecutedPercentAsString, 'numExecutedBranches' => $item['executedBranches'], 'numExecutableBranches' => $item['executableBranches'], 'pathsExecutedPercent' => Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths'])->asFloat(), 'pathsExecutedPercentAsString' => $pathsExecutedPercentAsString, 'numExecutedPaths' => $item['executedPaths'], 'numExecutablePaths' => $item['executablePaths'], 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), 'testedClassesPercent' => $testedClassesPercentage->asFloat(), 'testedClassesPercentAsString' => $testedClassesPercentage->asString(), 'crap' => $item['crap']]);
  30807. foreach ($item['methods'] as $method) {
  30808. $buffer .= $this->renderFunctionOrMethodItem($methodItemTemplate, $method, '&nbsp;');
  30809. }
  30810. }
  30811. return $buffer;
  30812. }
  30813. private function renderFunctionItems(array $functions, Template $template): string
  30814. {
  30815. if (empty($functions)) {
  30816. return '';
  30817. }
  30818. $buffer = '';
  30819. foreach ($functions as $function) {
  30820. $buffer .= $this->renderFunctionOrMethodItem($template, $function);
  30821. }
  30822. return $buffer;
  30823. }
  30824. private function renderFunctionOrMethodItem(Template $template, array $item, string $indent = ''): string
  30825. {
  30826. $numMethods = 0;
  30827. $numTestedMethods = 0;
  30828. if ($item['executableLines'] > 0) {
  30829. $numMethods = 1;
  30830. if ($item['executedLines'] === $item['executableLines']) {
  30831. $numTestedMethods = 1;
  30832. }
  30833. }
  30834. $executedLinesPercentage = Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines']);
  30835. $executedBranchesPercentage = Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches']);
  30836. $executedPathsPercentage = Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths']);
  30837. $testedMethodsPercentage = Percentage::fromFractionAndTotal($numTestedMethods, 1);
  30838. return $this->renderItemTemplate($template, ['name' => sprintf('%s<a href="#%d"><abbr title="%s">%s</abbr></a>', $indent, $item['startLine'], htmlspecialchars($item['signature'], $this->htmlSpecialCharsFlags), $item['functionName'] ?? $item['methodName']), 'numMethods' => $numMethods, 'numTestedMethods' => $numTestedMethods, 'linesExecutedPercent' => $executedLinesPercentage->asFloat(), 'linesExecutedPercentAsString' => $executedLinesPercentage->asString(), 'numExecutedLines' => $item['executedLines'], 'numExecutableLines' => $item['executableLines'], 'branchesExecutedPercent' => $executedBranchesPercentage->asFloat(), 'branchesExecutedPercentAsString' => $executedBranchesPercentage->asString(), 'numExecutedBranches' => $item['executedBranches'], 'numExecutableBranches' => $item['executableBranches'], 'pathsExecutedPercent' => $executedPathsPercentage->asFloat(), 'pathsExecutedPercentAsString' => $executedPathsPercentage->asString(), 'numExecutedPaths' => $item['executedPaths'], 'numExecutablePaths' => $item['executablePaths'], 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), 'crap' => $item['crap']]);
  30839. }
  30840. private function renderSourceWithLineCoverage(FileNode $node): string
  30841. {
  30842. $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
  30843. $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
  30844. $coverageData = $node->lineCoverageData();
  30845. $testData = $node->testData();
  30846. $codeLines = $this->loadFile($node->pathAsString());
  30847. $lines = '';
  30848. $i = 1;
  30849. foreach ($codeLines as $line) {
  30850. $trClass = '';
  30851. $popoverContent = '';
  30852. $popoverTitle = '';
  30853. if (array_key_exists($i, $coverageData)) {
  30854. $numTests = $coverageData[$i] ? count($coverageData[$i]) : 0;
  30855. if ($coverageData[$i] === null) {
  30856. $trClass = 'warning';
  30857. } elseif ($numTests === 0) {
  30858. $trClass = 'danger';
  30859. } else {
  30860. if ($numTests > 1) {
  30861. $popoverTitle = $numTests . ' tests cover line ' . $i;
  30862. } else {
  30863. $popoverTitle = '1 test covers line ' . $i;
  30864. }
  30865. $lineCss = 'covered-by-large-tests';
  30866. $popoverContent = '<ul>';
  30867. foreach ($coverageData[$i] as $test) {
  30868. if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
  30869. $lineCss = 'covered-by-medium-tests';
  30870. } elseif ($testData[$test]['size'] === 'small') {
  30871. $lineCss = 'covered-by-small-tests';
  30872. }
  30873. $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
  30874. }
  30875. $popoverContent .= '</ul>';
  30876. $trClass = $lineCss . ' popin';
  30877. }
  30878. }
  30879. $popover = '';
  30880. if (!empty($popoverTitle)) {
  30881. $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
  30882. }
  30883. $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
  30884. $i++;
  30885. }
  30886. $linesTemplate->setVar(['lines' => $lines]);
  30887. return $linesTemplate->render();
  30888. }
  30889. private function renderSourceWithBranchCoverage(FileNode $node): string
  30890. {
  30891. $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
  30892. $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
  30893. $functionCoverageData = $node->functionCoverageData();
  30894. $testData = $node->testData();
  30895. $codeLines = $this->loadFile($node->pathAsString());
  30896. $lineData = [];
  30897. /** @var int $line */
  30898. foreach (array_keys($codeLines) as $line) {
  30899. $lineData[$line + 1] = ['includedInBranches' => 0, 'includedInHitBranches' => 0, 'tests' => []];
  30900. }
  30901. foreach ($functionCoverageData as $method) {
  30902. foreach ($method['branches'] as $branch) {
  30903. foreach (range($branch['line_start'], $branch['line_end']) as $line) {
  30904. if (!isset($lineData[$line])) {
  30905. // blank line at end of file is sometimes included here
  30906. continue;
  30907. }
  30908. $lineData[$line]['includedInBranches']++;
  30909. if ($branch['hit']) {
  30910. $lineData[$line]['includedInHitBranches']++;
  30911. $lineData[$line]['tests'] = array_unique(array_merge($lineData[$line]['tests'], $branch['hit']));
  30912. }
  30913. }
  30914. }
  30915. }
  30916. $lines = '';
  30917. $i = 1;
  30918. /** @var string $line */
  30919. foreach ($codeLines as $line) {
  30920. $trClass = '';
  30921. $popover = '';
  30922. if ($lineData[$i]['includedInBranches'] > 0) {
  30923. $lineCss = 'success';
  30924. if ($lineData[$i]['includedInHitBranches'] === 0) {
  30925. $lineCss = 'danger';
  30926. } elseif ($lineData[$i]['includedInHitBranches'] !== $lineData[$i]['includedInBranches']) {
  30927. $lineCss = 'warning';
  30928. }
  30929. $popoverContent = '<ul>';
  30930. if (count($lineData[$i]['tests']) === 1) {
  30931. $popoverTitle = '1 test covers line ' . $i;
  30932. } else {
  30933. $popoverTitle = count($lineData[$i]['tests']) . ' tests cover line ' . $i;
  30934. }
  30935. $popoverTitle .= '. These are covering ' . $lineData[$i]['includedInHitBranches'] . ' out of the ' . $lineData[$i]['includedInBranches'] . ' code branches.';
  30936. foreach ($lineData[$i]['tests'] as $test) {
  30937. $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
  30938. }
  30939. $popoverContent .= '</ul>';
  30940. $trClass = $lineCss . ' popin';
  30941. $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
  30942. }
  30943. $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
  30944. $i++;
  30945. }
  30946. $linesTemplate->setVar(['lines' => $lines]);
  30947. return $linesTemplate->render();
  30948. }
  30949. private function renderSourceWithPathCoverage(FileNode $node): string
  30950. {
  30951. $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
  30952. $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
  30953. $functionCoverageData = $node->functionCoverageData();
  30954. $testData = $node->testData();
  30955. $codeLines = $this->loadFile($node->pathAsString());
  30956. $lineData = [];
  30957. /** @var int $line */
  30958. foreach (array_keys($codeLines) as $line) {
  30959. $lineData[$line + 1] = ['includedInPaths' => [], 'includedInHitPaths' => [], 'tests' => []];
  30960. }
  30961. foreach ($functionCoverageData as $method) {
  30962. foreach ($method['paths'] as $pathId => $path) {
  30963. foreach ($path['path'] as $branchTaken) {
  30964. foreach (range($method['branches'][$branchTaken]['line_start'], $method['branches'][$branchTaken]['line_end']) as $line) {
  30965. if (!isset($lineData[$line])) {
  30966. continue;
  30967. }
  30968. $lineData[$line]['includedInPaths'][] = $pathId;
  30969. if ($path['hit']) {
  30970. $lineData[$line]['includedInHitPaths'][] = $pathId;
  30971. $lineData[$line]['tests'] = array_unique(array_merge($lineData[$line]['tests'], $path['hit']));
  30972. }
  30973. }
  30974. }
  30975. }
  30976. }
  30977. $lines = '';
  30978. $i = 1;
  30979. /** @var string $line */
  30980. foreach ($codeLines as $line) {
  30981. $trClass = '';
  30982. $popover = '';
  30983. $includedInPathsCount = count(array_unique($lineData[$i]['includedInPaths']));
  30984. $includedInHitPathsCount = count(array_unique($lineData[$i]['includedInHitPaths']));
  30985. if ($includedInPathsCount > 0) {
  30986. $lineCss = 'success';
  30987. if ($includedInHitPathsCount === 0) {
  30988. $lineCss = 'danger';
  30989. } elseif ($includedInHitPathsCount !== $includedInPathsCount) {
  30990. $lineCss = 'warning';
  30991. }
  30992. $popoverContent = '<ul>';
  30993. if (count($lineData[$i]['tests']) === 1) {
  30994. $popoverTitle = '1 test covers line ' . $i;
  30995. } else {
  30996. $popoverTitle = count($lineData[$i]['tests']) . ' tests cover line ' . $i;
  30997. }
  30998. $popoverTitle .= '. These are covering ' . $includedInHitPathsCount . ' out of the ' . $includedInPathsCount . ' code paths.';
  30999. foreach ($lineData[$i]['tests'] as $test) {
  31000. $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
  31001. }
  31002. $popoverContent .= '</ul>';
  31003. $trClass = $lineCss . ' popin';
  31004. $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
  31005. }
  31006. $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
  31007. $i++;
  31008. }
  31009. $linesTemplate->setVar(['lines' => $lines]);
  31010. return $linesTemplate->render();
  31011. }
  31012. private function renderBranchStructure(FileNode $node): string
  31013. {
  31014. $branchesTemplate = new Template($this->templatePath . 'branches.html.dist', '{{', '}}');
  31015. $coverageData = $node->functionCoverageData();
  31016. $testData = $node->testData();
  31017. $codeLines = $this->loadFile($node->pathAsString());
  31018. $branches = '';
  31019. ksort($coverageData);
  31020. foreach ($coverageData as $methodName => $methodData) {
  31021. if (!$methodData['branches']) {
  31022. continue;
  31023. }
  31024. $branchStructure = '';
  31025. foreach ($methodData['branches'] as $branch) {
  31026. $branchStructure .= $this->renderBranchLines($branch, $codeLines, $testData);
  31027. }
  31028. if ($branchStructure !== '') {
  31029. // don't show empty branches
  31030. $branches .= '<h5 class="structure-heading"><a name="' . htmlspecialchars($methodName, $this->htmlSpecialCharsFlags) . '">' . $this->abbreviateMethodName($methodName) . '</a></h5>' . "\n";
  31031. $branches .= $branchStructure;
  31032. }
  31033. }
  31034. $branchesTemplate->setVar(['branches' => $branches]);
  31035. return $branchesTemplate->render();
  31036. }
  31037. private function renderBranchLines(array $branch, array $codeLines, array $testData): string
  31038. {
  31039. $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
  31040. $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
  31041. $lines = '';
  31042. $branchLines = range($branch['line_start'], $branch['line_end']);
  31043. sort($branchLines);
  31044. // sometimes end_line < start_line
  31045. /** @var int $line */
  31046. foreach ($branchLines as $line) {
  31047. if (!isset($codeLines[$line])) {
  31048. // blank line at end of file is sometimes included here
  31049. continue;
  31050. }
  31051. $popoverContent = '';
  31052. $popoverTitle = '';
  31053. $numTests = count($branch['hit']);
  31054. if ($numTests === 0) {
  31055. $trClass = 'danger';
  31056. } else {
  31057. $lineCss = 'covered-by-large-tests';
  31058. $popoverContent = '<ul>';
  31059. if ($numTests > 1) {
  31060. $popoverTitle = $numTests . ' tests cover this branch';
  31061. } else {
  31062. $popoverTitle = '1 test covers this branch';
  31063. }
  31064. foreach ($branch['hit'] as $test) {
  31065. if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
  31066. $lineCss = 'covered-by-medium-tests';
  31067. } elseif ($testData[$test]['size'] === 'small') {
  31068. $lineCss = 'covered-by-small-tests';
  31069. }
  31070. $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
  31071. }
  31072. $trClass = $lineCss . ' popin';
  31073. }
  31074. $popover = '';
  31075. if (!empty($popoverTitle)) {
  31076. $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
  31077. }
  31078. $lines .= $this->renderLine($singleLineTemplate, $line, $codeLines[$line - 1], $trClass, $popover);
  31079. }
  31080. if ($lines === '') {
  31081. return '';
  31082. }
  31083. $linesTemplate->setVar(['lines' => $lines]);
  31084. return $linesTemplate->render();
  31085. }
  31086. private function renderPathStructure(FileNode $node): string
  31087. {
  31088. $pathsTemplate = new Template($this->templatePath . 'paths.html.dist', '{{', '}}');
  31089. $coverageData = $node->functionCoverageData();
  31090. $testData = $node->testData();
  31091. $codeLines = $this->loadFile($node->pathAsString());
  31092. $paths = '';
  31093. ksort($coverageData);
  31094. foreach ($coverageData as $methodName => $methodData) {
  31095. if (!$methodData['paths']) {
  31096. continue;
  31097. }
  31098. $pathStructure = '';
  31099. if (count($methodData['paths']) > 100) {
  31100. $pathStructure .= '<p>' . count($methodData['paths']) . ' is too many paths to sensibly render, consider refactoring your code to bring this number down.</p>';
  31101. continue;
  31102. }
  31103. foreach ($methodData['paths'] as $path) {
  31104. $pathStructure .= $this->renderPathLines($path, $methodData['branches'], $codeLines, $testData);
  31105. }
  31106. if ($pathStructure !== '') {
  31107. $paths .= '<h5 class="structure-heading"><a name="' . htmlspecialchars($methodName, $this->htmlSpecialCharsFlags) . '">' . $this->abbreviateMethodName($methodName) . '</a></h5>' . "\n";
  31108. $paths .= $pathStructure;
  31109. }
  31110. }
  31111. $pathsTemplate->setVar(['paths' => $paths]);
  31112. return $pathsTemplate->render();
  31113. }
  31114. private function renderPathLines(array $path, array $branches, array $codeLines, array $testData): string
  31115. {
  31116. $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
  31117. $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
  31118. $lines = '';
  31119. $first = \true;
  31120. foreach ($path['path'] as $branchId) {
  31121. if ($first) {
  31122. $first = \false;
  31123. } else {
  31124. $lines .= ' <tr><td colspan="2">&nbsp;</td></tr>' . "\n";
  31125. }
  31126. $branchLines = range($branches[$branchId]['line_start'], $branches[$branchId]['line_end']);
  31127. sort($branchLines);
  31128. // sometimes end_line < start_line
  31129. /** @var int $line */
  31130. foreach ($branchLines as $line) {
  31131. if (!isset($codeLines[$line])) {
  31132. // blank line at end of file is sometimes included here
  31133. continue;
  31134. }
  31135. $popoverContent = '';
  31136. $popoverTitle = '';
  31137. $numTests = count($path['hit']);
  31138. if ($numTests === 0) {
  31139. $trClass = 'danger';
  31140. } else {
  31141. $lineCss = 'covered-by-large-tests';
  31142. $popoverContent = '<ul>';
  31143. if ($numTests > 1) {
  31144. $popoverTitle = $numTests . ' tests cover this path';
  31145. } else {
  31146. $popoverTitle = '1 test covers this path';
  31147. }
  31148. foreach ($path['hit'] as $test) {
  31149. if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
  31150. $lineCss = 'covered-by-medium-tests';
  31151. } elseif ($testData[$test]['size'] === 'small') {
  31152. $lineCss = 'covered-by-small-tests';
  31153. }
  31154. $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
  31155. }
  31156. $trClass = $lineCss . ' popin';
  31157. }
  31158. $popover = '';
  31159. if (!empty($popoverTitle)) {
  31160. $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
  31161. }
  31162. $lines .= $this->renderLine($singleLineTemplate, $line, $codeLines[$line - 1], $trClass, $popover);
  31163. }
  31164. }
  31165. if ($lines === '') {
  31166. return '';
  31167. }
  31168. $linesTemplate->setVar(['lines' => $lines]);
  31169. return $linesTemplate->render();
  31170. }
  31171. private function renderLine(Template $template, int $lineNumber, string $lineContent, string $class, string $popover): string
  31172. {
  31173. $template->setVar(['lineNumber' => $lineNumber, 'lineContent' => $lineContent, 'class' => $class, 'popover' => $popover]);
  31174. return $template->render();
  31175. }
  31176. private function loadFile(string $file): array
  31177. {
  31178. if (isset(self::$formattedSourceCache[$file])) {
  31179. return self::$formattedSourceCache[$file];
  31180. }
  31181. $buffer = file_get_contents($file);
  31182. $tokens = token_get_all($buffer);
  31183. $result = [''];
  31184. $i = 0;
  31185. $stringFlag = \false;
  31186. $fileEndsWithNewLine = str_ends_with($buffer, "\n");
  31187. unset($buffer);
  31188. foreach ($tokens as $j => $token) {
  31189. if (is_string($token)) {
  31190. if ($token === '"' && $tokens[$j - 1] !== '\\') {
  31191. $result[$i] .= sprintf('<span class="string">%s</span>', htmlspecialchars($token, $this->htmlSpecialCharsFlags));
  31192. $stringFlag = !$stringFlag;
  31193. } else {
  31194. $result[$i] .= sprintf('<span class="keyword">%s</span>', htmlspecialchars($token, $this->htmlSpecialCharsFlags));
  31195. }
  31196. continue;
  31197. }
  31198. [$token, $value] = $token;
  31199. $value = str_replace(["\t", ' '], ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'], htmlspecialchars($value, $this->htmlSpecialCharsFlags));
  31200. if ($value === "\n") {
  31201. $result[++$i] = '';
  31202. } else {
  31203. $lines = explode("\n", $value);
  31204. foreach ($lines as $jj => $line) {
  31205. $line = trim($line);
  31206. if ($line !== '') {
  31207. if ($stringFlag) {
  31208. $colour = 'string';
  31209. } else {
  31210. $colour = 'default';
  31211. if ($this->isInlineHtml($token)) {
  31212. $colour = 'html';
  31213. } elseif ($this->isComment($token)) {
  31214. $colour = 'comment';
  31215. } elseif ($this->isKeyword($token)) {
  31216. $colour = 'keyword';
  31217. }
  31218. }
  31219. $result[$i] .= sprintf('<span class="%s">%s</span>', $colour, $line);
  31220. }
  31221. if (isset($lines[$jj + 1])) {
  31222. $result[++$i] = '';
  31223. }
  31224. }
  31225. }
  31226. }
  31227. if ($fileEndsWithNewLine) {
  31228. unset($result[count($result) - 1]);
  31229. }
  31230. self::$formattedSourceCache[$file] = $result;
  31231. return $result;
  31232. }
  31233. private function abbreviateClassName(string $className): string
  31234. {
  31235. $tmp = explode('\\', $className);
  31236. if (count($tmp) > 1) {
  31237. $className = sprintf('<abbr title="%s">%s</abbr>', $className, array_pop($tmp));
  31238. }
  31239. return $className;
  31240. }
  31241. private function abbreviateMethodName(string $methodName): string
  31242. {
  31243. $parts = explode('->', $methodName);
  31244. if (count($parts) === 2) {
  31245. return $this->abbreviateClassName($parts[0]) . '->' . $parts[1];
  31246. }
  31247. return $methodName;
  31248. }
  31249. private function createPopoverContentForTest(string $test, array $testData): string
  31250. {
  31251. $testCSS = '';
  31252. switch ($testData['status']) {
  31253. case 'success':
  31254. $testCSS = match ($testData['size']) {
  31255. 'small' => ' class="covered-by-small-tests"',
  31256. 'medium' => ' class="covered-by-medium-tests"',
  31257. // no break
  31258. default => ' class="covered-by-large-tests"',
  31259. };
  31260. break;
  31261. case 'failure':
  31262. $testCSS = ' class="danger"';
  31263. break;
  31264. }
  31265. return sprintf('<li%s>%s</li>', $testCSS, htmlspecialchars($test, $this->htmlSpecialCharsFlags));
  31266. }
  31267. private function isComment(int $token): bool
  31268. {
  31269. return $token === T_COMMENT || $token === T_DOC_COMMENT;
  31270. }
  31271. private function isInlineHtml(int $token): bool
  31272. {
  31273. return $token === T_INLINE_HTML;
  31274. }
  31275. private function isKeyword(int $token): bool
  31276. {
  31277. return isset(self::KEYWORD_TOKENS[$token]);
  31278. }
  31279. }
  31280. <hr/>
  31281. <h4>Branches</h4>
  31282. <p>
  31283. Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
  31284. necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
  31285. Please also be aware that some branches may be implicit rather than explicit, e.g. an <code>if</code> statement
  31286. <i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
  31287. </p>
  31288. {{branches}}
  31289. <div class="progress">
  31290. <div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
  31291. <span class="sr-only">{{percent}}% covered ({{level}})</span>
  31292. </div>
  31293. </div>
  31294. <div class="progress">
  31295. <div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
  31296. <span class="sr-only">{{percent}}% covered ({{level}})</span>
  31297. </div>
  31298. </div>
  31299. /*!
  31300. * Bootstrap v4.6.2 (https://getbootstrap.com/)
  31301. * Copyright 2011-2022 The Bootstrap Authors
  31302. * Copyright 2011-2022 Twitter, Inc.
  31303. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
  31304. */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:.875em;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.width{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.width{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:1px solid #adb5bd}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background-color:transparent;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentcolor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentcolor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
  31305. /*# sourceMappingURL=bootstrap.min.css.map */.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc}.octicon {
  31306. display: inline-block;
  31307. vertical-align: text-top;
  31308. fill: currentColor;
  31309. }
  31310. body {
  31311. font-family: sans-serif;
  31312. font-size: 1em;
  31313. font-kerning: normal;
  31314. font-variant-ligatures: common-ligatures;
  31315. text-rendering: optimizeLegibility;
  31316. padding-top: 10px;
  31317. }
  31318. .popover {
  31319. max-width: none;
  31320. }
  31321. .octicon {
  31322. margin-right:.25em;
  31323. vertical-align: baseline;
  31324. width: 0.75em;
  31325. }
  31326. .table-bordered>thead>tr>td {
  31327. border-bottom-width: 1px;
  31328. }
  31329. .table tbody>tr>td, .table thead>tr>td {
  31330. padding-top: 3px;
  31331. padding-bottom: 3px;
  31332. }
  31333. .table-condensed tbody>tr>td {
  31334. padding-top: 0;
  31335. padding-bottom: 0;
  31336. }
  31337. .table .progress {
  31338. margin-bottom: inherit;
  31339. }
  31340. .table-borderless th, .table-borderless td {
  31341. border: 0 !important;
  31342. }
  31343. .table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
  31344. background-color: {{success-low}};
  31345. }
  31346. .table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
  31347. background-color: {{success-medium}};
  31348. }
  31349. .table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
  31350. background-color: {{success-high}};
  31351. }
  31352. .table tbody tr.warning, .table tbody td.warning, li.warning, span.warning {
  31353. background-color: {{warning}};
  31354. }
  31355. .table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
  31356. background-color: {{danger}};
  31357. }
  31358. .table tbody td.info {
  31359. background-color: #d9edf7;
  31360. }
  31361. td.big {
  31362. vertical-align: middle;
  31363. width: 117px;
  31364. }
  31365. td.small {
  31366. }
  31367. td.codeLine {
  31368. font-family: "Source Code Pro", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  31369. white-space: pre-wrap;
  31370. }
  31371. td span.comment {
  31372. color: #888a85;
  31373. }
  31374. td span.default {
  31375. color: #2e3436;
  31376. }
  31377. td span.html {
  31378. color: #888a85;
  31379. }
  31380. td span.keyword {
  31381. color: #2e3436;
  31382. font-weight: bold;
  31383. }
  31384. pre span.string {
  31385. color: #2e3436;
  31386. }
  31387. span.success, span.warning, span.danger {
  31388. margin-right: 2px;
  31389. padding-left: 10px;
  31390. padding-right: 10px;
  31391. text-align: center;
  31392. }
  31393. #toplink {
  31394. position: fixed;
  31395. left: 5px;
  31396. bottom: 5px;
  31397. outline: 0;
  31398. }
  31399. svg text {
  31400. font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
  31401. font-size: 11px;
  31402. color: #666;
  31403. fill: #666;
  31404. }
  31405. .scrollbox {
  31406. height:245px;
  31407. overflow-x:scroll;
  31408. overflow-y:scroll;
  31409. }
  31410. table + .structure-heading {
  31411. border-top: 1px solid lightgrey;
  31412. padding-top: 0.5em;
  31413. }
  31414. .legend {
  31415. font-weight: bold;
  31416. margin-right: 2px;
  31417. padding-left: 10px;
  31418. padding-right: 10px;
  31419. text-align: center;
  31420. }
  31421. .covered-by-small-tests {
  31422. background-color: {{success-high}};
  31423. }
  31424. .covered-by-medium-tests {
  31425. background-color: {{success-medium}};
  31426. }
  31427. .covered-by-large-tests {
  31428. background-color: {{success-low}};
  31429. }
  31430. .not-covered {
  31431. background-color: {{danger}};
  31432. }
  31433. .not-coverable {
  31434. background-color: {{warning}};
  31435. }
  31436. <!DOCTYPE html>
  31437. <html lang="en">
  31438. <head>
  31439. <meta charset="UTF-8">
  31440. <title>Dashboard for {{full_path}}</title>
  31441. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  31442. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  31443. <link href="{{path_to_root}}_css/nv.d3.min.css?v={{version}}" rel="stylesheet" type="text/css">
  31444. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  31445. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  31446. </head>
  31447. <body>
  31448. <header>
  31449. <div class="container-fluid">
  31450. <div class="row">
  31451. <div class="col-md-12">
  31452. <nav aria-label="breadcrumb">
  31453. <ol class="breadcrumb">
  31454. {{breadcrumbs}}
  31455. </ol>
  31456. </nav>
  31457. </div>
  31458. </div>
  31459. </div>
  31460. </header>
  31461. <div class="container-fluid">
  31462. <div class="row">
  31463. <div class="col-md-12">
  31464. <h2>Classes</h2>
  31465. </div>
  31466. </div>
  31467. <div class="row">
  31468. <div class="col-md-6">
  31469. <h3>Coverage Distribution</h3>
  31470. <div id="classCoverageDistribution" style="height: 300px;">
  31471. <svg></svg>
  31472. </div>
  31473. </div>
  31474. <div class="col-md-6">
  31475. <h3>Complexity</h3>
  31476. <div id="classComplexity" style="height: 300px;">
  31477. <svg></svg>
  31478. </div>
  31479. </div>
  31480. </div>
  31481. <div class="row">
  31482. <div class="col-md-6">
  31483. <h3>Insufficient Coverage</h3>
  31484. <div class="scrollbox">
  31485. <table class="table">
  31486. <thead>
  31487. <tr>
  31488. <th>Class</th>
  31489. <th class="text-right">Coverage</th>
  31490. </tr>
  31491. </thead>
  31492. <tbody>
  31493. {{insufficient_coverage_classes}}
  31494. </tbody>
  31495. </table>
  31496. </div>
  31497. </div>
  31498. <div class="col-md-6">
  31499. <h3>Project Risks</h3>
  31500. <div class="scrollbox">
  31501. <table class="table">
  31502. <thead>
  31503. <tr>
  31504. <th>Class</th>
  31505. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  31506. </tr>
  31507. </thead>
  31508. <tbody>
  31509. {{project_risks_classes}}
  31510. </tbody>
  31511. </table>
  31512. </div>
  31513. </div>
  31514. </div>
  31515. <div class="row">
  31516. <div class="col-md-12">
  31517. <h2>Methods</h2>
  31518. </div>
  31519. </div>
  31520. <div class="row">
  31521. <div class="col-md-6">
  31522. <h3>Coverage Distribution</h3>
  31523. <div id="methodCoverageDistribution" style="height: 300px;">
  31524. <svg></svg>
  31525. </div>
  31526. </div>
  31527. <div class="col-md-6">
  31528. <h3>Complexity</h3>
  31529. <div id="methodComplexity" style="height: 300px;">
  31530. <svg></svg>
  31531. </div>
  31532. </div>
  31533. </div>
  31534. <div class="row">
  31535. <div class="col-md-6">
  31536. <h3>Insufficient Coverage</h3>
  31537. <div class="scrollbox">
  31538. <table class="table">
  31539. <thead>
  31540. <tr>
  31541. <th>Method</th>
  31542. <th class="text-right">Coverage</th>
  31543. </tr>
  31544. </thead>
  31545. <tbody>
  31546. {{insufficient_coverage_methods}}
  31547. </tbody>
  31548. </table>
  31549. </div>
  31550. </div>
  31551. <div class="col-md-6">
  31552. <h3>Project Risks</h3>
  31553. <div class="scrollbox">
  31554. <table class="table">
  31555. <thead>
  31556. <tr>
  31557. <th>Method</th>
  31558. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  31559. </tr>
  31560. </thead>
  31561. <tbody>
  31562. {{project_risks_methods}}
  31563. </tbody>
  31564. </table>
  31565. </div>
  31566. </div>
  31567. </div>
  31568. <footer>
  31569. <hr/>
  31570. <p>
  31571. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  31572. </p>
  31573. </footer>
  31574. </div>
  31575. <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
  31576. <script src="{{path_to_root}}_js/d3.min.js?v={{version}}" type="text/javascript"></script>
  31577. <script src="{{path_to_root}}_js/nv.d3.min.js?v={{version}}" type="text/javascript"></script>
  31578. <script type="text/javascript">
  31579. $(document).ready(function() {
  31580. nv.addGraph(function() {
  31581. var chart = nv.models.multiBarChart();
  31582. chart.tooltips(false)
  31583. .showControls(false)
  31584. .showLegend(false)
  31585. .reduceXTicks(false)
  31586. .staggerLabels(true)
  31587. .yAxis.tickFormat(d3.format('d'));
  31588. d3.select('#classCoverageDistribution svg')
  31589. .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
  31590. .transition().duration(500).call(chart);
  31591. nv.utils.windowResize(chart.update);
  31592. return chart;
  31593. });
  31594. nv.addGraph(function() {
  31595. var chart = nv.models.multiBarChart();
  31596. chart.tooltips(false)
  31597. .showControls(false)
  31598. .showLegend(false)
  31599. .reduceXTicks(false)
  31600. .staggerLabels(true)
  31601. .yAxis.tickFormat(d3.format('d'));
  31602. d3.select('#methodCoverageDistribution svg')
  31603. .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
  31604. .transition().duration(500).call(chart);
  31605. nv.utils.windowResize(chart.update);
  31606. return chart;
  31607. });
  31608. function getCoverageDistributionData(data, label) {
  31609. var labels = [
  31610. '0%',
  31611. '0-10%',
  31612. '10-20%',
  31613. '20-30%',
  31614. '30-40%',
  31615. '40-50%',
  31616. '50-60%',
  31617. '60-70%',
  31618. '70-80%',
  31619. '80-90%',
  31620. '90-100%',
  31621. '100%'
  31622. ];
  31623. var values = [];
  31624. $.each(labels, function(key) {
  31625. values.push({x: labels[key], y: data[key]});
  31626. });
  31627. return [
  31628. {
  31629. key: label,
  31630. values: values,
  31631. color: "#4572A7"
  31632. }
  31633. ];
  31634. }
  31635. nv.addGraph(function() {
  31636. var chart = nv.models.scatterChart()
  31637. .showDistX(true)
  31638. .showDistY(true)
  31639. .showLegend(false)
  31640. .forceX([0, 100]);
  31641. chart.tooltipContent(function(graph) {
  31642. return '<p>' + graph.point.class + '</p>';
  31643. });
  31644. chart.xAxis.axisLabel('Code Coverage (in percent)');
  31645. chart.yAxis.axisLabel('Cyclomatic Complexity');
  31646. d3.select('#classComplexity svg')
  31647. .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
  31648. .transition()
  31649. .duration(500)
  31650. .call(chart);
  31651. nv.utils.windowResize(chart.update);
  31652. return chart;
  31653. });
  31654. nv.addGraph(function() {
  31655. var chart = nv.models.scatterChart()
  31656. .showDistX(true)
  31657. .showDistY(true)
  31658. .showLegend(false)
  31659. .forceX([0, 100]);
  31660. chart.tooltipContent(function(graph) {
  31661. return '<p>' + graph.point.class + '</p>';
  31662. });
  31663. chart.xAxis.axisLabel('Code Coverage (in percent)');
  31664. chart.yAxis.axisLabel('Method Complexity');
  31665. d3.select('#methodComplexity svg')
  31666. .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
  31667. .transition()
  31668. .duration(500)
  31669. .call(chart);
  31670. nv.utils.windowResize(chart.update);
  31671. return chart;
  31672. });
  31673. function getComplexityData(data, label) {
  31674. var values = [];
  31675. $.each(data, function(key) {
  31676. var value = Math.round(data[key][0]*100) / 100;
  31677. values.push({
  31678. x: value,
  31679. y: data[key][1],
  31680. class: data[key][2],
  31681. size: 0.05,
  31682. shape: 'diamond'
  31683. });
  31684. });
  31685. return [
  31686. {
  31687. key: label,
  31688. values: values,
  31689. color: "#4572A7"
  31690. }
  31691. ];
  31692. }
  31693. });
  31694. </script>
  31695. </body>
  31696. </html>
  31697. <!DOCTYPE html>
  31698. <html lang="en">
  31699. <head>
  31700. <meta charset="UTF-8">
  31701. <title>Dashboard for {{full_path}}</title>
  31702. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  31703. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  31704. <link href="{{path_to_root}}_css/nv.d3.min.css?v={{version}}" rel="stylesheet" type="text/css">
  31705. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  31706. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  31707. </head>
  31708. <body>
  31709. <header>
  31710. <div class="container-fluid">
  31711. <div class="row">
  31712. <div class="col-md-12">
  31713. <nav aria-label="breadcrumb">
  31714. <ol class="breadcrumb">
  31715. {{breadcrumbs}}
  31716. </ol>
  31717. </nav>
  31718. </div>
  31719. </div>
  31720. </div>
  31721. </header>
  31722. <div class="container-fluid">
  31723. <div class="row">
  31724. <div class="col-md-12">
  31725. <h2>Classes</h2>
  31726. </div>
  31727. </div>
  31728. <div class="row">
  31729. <div class="col-md-6">
  31730. <h3>Coverage Distribution</h3>
  31731. <div id="classCoverageDistribution" style="height: 300px;">
  31732. <svg></svg>
  31733. </div>
  31734. </div>
  31735. <div class="col-md-6">
  31736. <h3>Complexity</h3>
  31737. <div id="classComplexity" style="height: 300px;">
  31738. <svg></svg>
  31739. </div>
  31740. </div>
  31741. </div>
  31742. <div class="row">
  31743. <div class="col-md-6">
  31744. <h3>Insufficient Coverage</h3>
  31745. <div class="scrollbox">
  31746. <table class="table">
  31747. <thead>
  31748. <tr>
  31749. <th>Class</th>
  31750. <th class="text-right">Coverage</th>
  31751. </tr>
  31752. </thead>
  31753. <tbody>
  31754. {{insufficient_coverage_classes}}
  31755. </tbody>
  31756. </table>
  31757. </div>
  31758. </div>
  31759. <div class="col-md-6">
  31760. <h3>Project Risks</h3>
  31761. <div class="scrollbox">
  31762. <table class="table">
  31763. <thead>
  31764. <tr>
  31765. <th>Class</th>
  31766. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  31767. </tr>
  31768. </thead>
  31769. <tbody>
  31770. {{project_risks_classes}}
  31771. </tbody>
  31772. </table>
  31773. </div>
  31774. </div>
  31775. </div>
  31776. <div class="row">
  31777. <div class="col-md-12">
  31778. <h2>Methods</h2>
  31779. </div>
  31780. </div>
  31781. <div class="row">
  31782. <div class="col-md-6">
  31783. <h3>Coverage Distribution</h3>
  31784. <div id="methodCoverageDistribution" style="height: 300px;">
  31785. <svg></svg>
  31786. </div>
  31787. </div>
  31788. <div class="col-md-6">
  31789. <h3>Complexity</h3>
  31790. <div id="methodComplexity" style="height: 300px;">
  31791. <svg></svg>
  31792. </div>
  31793. </div>
  31794. </div>
  31795. <div class="row">
  31796. <div class="col-md-6">
  31797. <h3>Insufficient Coverage</h3>
  31798. <div class="scrollbox">
  31799. <table class="table">
  31800. <thead>
  31801. <tr>
  31802. <th>Method</th>
  31803. <th class="text-right">Coverage</th>
  31804. </tr>
  31805. </thead>
  31806. <tbody>
  31807. {{insufficient_coverage_methods}}
  31808. </tbody>
  31809. </table>
  31810. </div>
  31811. </div>
  31812. <div class="col-md-6">
  31813. <h3>Project Risks</h3>
  31814. <div class="scrollbox">
  31815. <table class="table">
  31816. <thead>
  31817. <tr>
  31818. <th>Method</th>
  31819. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  31820. </tr>
  31821. </thead>
  31822. <tbody>
  31823. {{project_risks_methods}}
  31824. </tbody>
  31825. </table>
  31826. </div>
  31827. </div>
  31828. </div>
  31829. <footer>
  31830. <hr/>
  31831. <p>
  31832. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  31833. </p>
  31834. </footer>
  31835. </div>
  31836. <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
  31837. <script src="{{path_to_root}}_js/d3.min.js?v={{version}}" type="text/javascript"></script>
  31838. <script src="{{path_to_root}}_js/nv.d3.min.js?v={{version}}" type="text/javascript"></script>
  31839. <script type="text/javascript">
  31840. $(document).ready(function() {
  31841. nv.addGraph(function() {
  31842. var chart = nv.models.multiBarChart();
  31843. chart.tooltips(false)
  31844. .showControls(false)
  31845. .showLegend(false)
  31846. .reduceXTicks(false)
  31847. .staggerLabels(true)
  31848. .yAxis.tickFormat(d3.format('d'));
  31849. d3.select('#classCoverageDistribution svg')
  31850. .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
  31851. .transition().duration(500).call(chart);
  31852. nv.utils.windowResize(chart.update);
  31853. return chart;
  31854. });
  31855. nv.addGraph(function() {
  31856. var chart = nv.models.multiBarChart();
  31857. chart.tooltips(false)
  31858. .showControls(false)
  31859. .showLegend(false)
  31860. .reduceXTicks(false)
  31861. .staggerLabels(true)
  31862. .yAxis.tickFormat(d3.format('d'));
  31863. d3.select('#methodCoverageDistribution svg')
  31864. .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
  31865. .transition().duration(500).call(chart);
  31866. nv.utils.windowResize(chart.update);
  31867. return chart;
  31868. });
  31869. function getCoverageDistributionData(data, label) {
  31870. var labels = [
  31871. '0%',
  31872. '0-10%',
  31873. '10-20%',
  31874. '20-30%',
  31875. '30-40%',
  31876. '40-50%',
  31877. '50-60%',
  31878. '60-70%',
  31879. '70-80%',
  31880. '80-90%',
  31881. '90-100%',
  31882. '100%'
  31883. ];
  31884. var values = [];
  31885. $.each(labels, function(key) {
  31886. values.push({x: labels[key], y: data[key]});
  31887. });
  31888. return [
  31889. {
  31890. key: label,
  31891. values: values,
  31892. color: "#4572A7"
  31893. }
  31894. ];
  31895. }
  31896. nv.addGraph(function() {
  31897. var chart = nv.models.scatterChart()
  31898. .showDistX(true)
  31899. .showDistY(true)
  31900. .showLegend(false)
  31901. .forceX([0, 100]);
  31902. chart.tooltipContent(function(graph) {
  31903. return '<p>' + graph.point.class + '</p>';
  31904. });
  31905. chart.xAxis.axisLabel('Code Coverage (in percent)');
  31906. chart.yAxis.axisLabel('Cyclomatic Complexity');
  31907. d3.select('#classComplexity svg')
  31908. .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
  31909. .transition()
  31910. .duration(500)
  31911. .call(chart);
  31912. nv.utils.windowResize(chart.update);
  31913. return chart;
  31914. });
  31915. nv.addGraph(function() {
  31916. var chart = nv.models.scatterChart()
  31917. .showDistX(true)
  31918. .showDistY(true)
  31919. .showLegend(false)
  31920. .forceX([0, 100]);
  31921. chart.tooltipContent(function(graph) {
  31922. return '<p>' + graph.point.class + '</p>';
  31923. });
  31924. chart.xAxis.axisLabel('Code Coverage (in percent)');
  31925. chart.yAxis.axisLabel('Method Complexity');
  31926. d3.select('#methodComplexity svg')
  31927. .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
  31928. .transition()
  31929. .duration(500)
  31930. .call(chart);
  31931. nv.utils.windowResize(chart.update);
  31932. return chart;
  31933. });
  31934. function getComplexityData(data, label) {
  31935. var values = [];
  31936. $.each(data, function(key) {
  31937. var value = Math.round(data[key][0]*100) / 100;
  31938. values.push({
  31939. x: value,
  31940. y: data[key][1],
  31941. class: data[key][2],
  31942. size: 0.05,
  31943. shape: 'diamond'
  31944. });
  31945. });
  31946. return [
  31947. {
  31948. key: label,
  31949. values: values,
  31950. color: "#4572A7"
  31951. }
  31952. ];
  31953. }
  31954. });
  31955. </script>
  31956. </body>
  31957. </html>
  31958. <!DOCTYPE html>
  31959. <html lang="en">
  31960. <head>
  31961. <meta charset="UTF-8">
  31962. <title>Code Coverage for {{full_path}}</title>
  31963. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  31964. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  31965. <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
  31966. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  31967. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  31968. </head>
  31969. <body>
  31970. <header>
  31971. <div class="container-fluid">
  31972. <div class="row">
  31973. <div class="col-md-12">
  31974. <nav aria-label="breadcrumb">
  31975. <ol class="breadcrumb">
  31976. {{breadcrumbs}}
  31977. </ol>
  31978. </nav>
  31979. </div>
  31980. </div>
  31981. </div>
  31982. </header>
  31983. <div class="container-fluid">
  31984. <div class="table-responsive">
  31985. <table class="table table-bordered">
  31986. <thead>
  31987. <tr>
  31988. <td>&nbsp;</td>
  31989. <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
  31990. </tr>
  31991. <tr>
  31992. <td>&nbsp;</td>
  31993. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  31994. <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
  31995. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  31996. </tr>
  31997. </thead>
  31998. <tbody>
  31999. {{items}}
  32000. </tbody>
  32001. </table>
  32002. </div>
  32003. <footer>
  32004. <hr/>
  32005. <h4>Legend</h4>
  32006. <p>
  32007. <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
  32008. <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
  32009. <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
  32010. </p>
  32011. <p>
  32012. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  32013. </p>
  32014. </footer>
  32015. </div>
  32016. </body>
  32017. </html>
  32018. <!DOCTYPE html>
  32019. <html lang="en">
  32020. <head>
  32021. <meta charset="UTF-8">
  32022. <title>Code Coverage for {{full_path}}</title>
  32023. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  32024. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  32025. <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
  32026. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  32027. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  32028. </head>
  32029. <body>
  32030. <header>
  32031. <div class="container-fluid">
  32032. <div class="row">
  32033. <div class="col-md-12">
  32034. <nav aria-label="breadcrumb">
  32035. <ol class="breadcrumb">
  32036. {{breadcrumbs}}
  32037. </ol>
  32038. </nav>
  32039. </div>
  32040. </div>
  32041. </div>
  32042. </header>
  32043. <div class="container-fluid">
  32044. <div class="table-responsive">
  32045. <table class="table table-bordered">
  32046. <thead>
  32047. <tr>
  32048. <td>&nbsp;</td>
  32049. <td colspan="15"><div align="center"><strong>Code Coverage</strong></div></td>
  32050. </tr>
  32051. <tr>
  32052. <td>&nbsp;</td>
  32053. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  32054. <td colspan="3"><div align="center"><strong>Branches</strong></div></td>
  32055. <td colspan="3"><div align="center"><strong>Paths</strong></div></td>
  32056. <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
  32057. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  32058. </tr>
  32059. </thead>
  32060. <tbody>
  32061. {{items}}
  32062. </tbody>
  32063. </table>
  32064. </div>
  32065. <footer>
  32066. <hr/>
  32067. <h4>Legend</h4>
  32068. <p>
  32069. <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
  32070. <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
  32071. <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
  32072. </p>
  32073. <p>
  32074. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  32075. </p>
  32076. </footer>
  32077. </div>
  32078. </body>
  32079. </html>
  32080. <tr>
  32081. <td class="{{lines_level}}">{{icon}}{{name}}</td>
  32082. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32083. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32084. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32085. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32086. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32087. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32088. <td class="{{classes_level}} big">{{classes_bar}}</td>
  32089. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  32090. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  32091. </tr>
  32092. <tr>
  32093. <td class="{{lines_level}}">{{icon}}{{name}}</td>
  32094. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32095. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32096. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32097. <td class="{{branches_level}} big">{{branches_bar}}</td>
  32098. <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
  32099. <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
  32100. <td class="{{paths_level}} big">{{paths_bar}}</td>
  32101. <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
  32102. <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
  32103. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32104. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32105. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32106. <td class="{{classes_level}} big">{{classes_bar}}</td>
  32107. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  32108. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  32109. </tr>
  32110. <!DOCTYPE html>
  32111. <html lang="en">
  32112. <head>
  32113. <meta charset="UTF-8">
  32114. <title>Code Coverage for {{full_path}}</title>
  32115. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  32116. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  32117. <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
  32118. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  32119. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  32120. </head>
  32121. <body>
  32122. <header>
  32123. <div class="container-fluid">
  32124. <div class="row">
  32125. <div class="col-md-12">
  32126. <nav aria-label="breadcrumb">
  32127. <ol class="breadcrumb">
  32128. {{breadcrumbs}}
  32129. </ol>
  32130. </nav>
  32131. </div>
  32132. </div>
  32133. </div>
  32134. </header>
  32135. <div class="container-fluid">
  32136. <div class="table-responsive">
  32137. <table class="table table-bordered">
  32138. <thead>
  32139. <tr>
  32140. <td>&nbsp;</td>
  32141. <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
  32142. </tr>
  32143. <tr>
  32144. <td>&nbsp;</td>
  32145. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  32146. <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
  32147. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  32148. </tr>
  32149. </thead>
  32150. <tbody>
  32151. {{items}}
  32152. </tbody>
  32153. </table>
  32154. </div>
  32155. {{lines}}
  32156. {{structure}}
  32157. <footer>
  32158. <hr/>
  32159. <h4>Legend</h4>
  32160. {{legend}}
  32161. <p>
  32162. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  32163. </p>
  32164. <a title="Back to the top" id="toplink" href="#">
  32165. <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
  32166. </a>
  32167. </footer>
  32168. </div>
  32169. <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
  32170. <script src="{{path_to_root}}_js/popper.min.js?v={{version}}" type="text/javascript"></script>
  32171. <script src="{{path_to_root}}_js/bootstrap.min.js?v={{version}}" type="text/javascript"></script>
  32172. <script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
  32173. </body>
  32174. </html>
  32175. <!DOCTYPE html>
  32176. <html lang="en">
  32177. <head>
  32178. <meta charset="UTF-8">
  32179. <title>Code Coverage for {{full_path}}</title>
  32180. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  32181. <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
  32182. <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
  32183. <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
  32184. <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
  32185. </head>
  32186. <body>
  32187. <header>
  32188. <div class="container-fluid">
  32189. <div class="row">
  32190. <div class="col-md-12">
  32191. <nav aria-label="breadcrumb">
  32192. <ol class="breadcrumb">
  32193. {{breadcrumbs}}
  32194. </ol>
  32195. </nav>
  32196. </div>
  32197. </div>
  32198. </div>
  32199. </header>
  32200. <div class="container-fluid">
  32201. <div class="table-responsive">
  32202. <table class="table table-bordered">
  32203. <thead>
  32204. <tr>
  32205. <td>&nbsp;</td>
  32206. <td colspan="16"><div align="center"><strong>Code Coverage</strong></div></td>
  32207. </tr>
  32208. <tr>
  32209. <td>&nbsp;</td>
  32210. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  32211. <td colspan="3"><div align="center"><strong>Branches</strong></div></td>
  32212. <td colspan="3"><div align="center"><strong>Paths</strong></div></td>
  32213. <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
  32214. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  32215. </tr>
  32216. </thead>
  32217. <tbody>
  32218. {{items}}
  32219. </tbody>
  32220. </table>
  32221. </div>
  32222. {{lines}}
  32223. {{structure}}
  32224. <footer>
  32225. <hr/>
  32226. <h4>Legend</h4>
  32227. {{legend}}
  32228. <p>
  32229. <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
  32230. </p>
  32231. <a title="Back to the top" id="toplink" href="#">
  32232. <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
  32233. </a>
  32234. </footer>
  32235. </div>
  32236. <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
  32237. <script src="{{path_to_root}}_js/popper.min.js?v={{version}}" type="text/javascript"></script>
  32238. <script src="{{path_to_root}}_js/bootstrap.min.js?v={{version}}" type="text/javascript"></script>
  32239. <script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
  32240. </body>
  32241. </html>
  32242. <tr>
  32243. <td class="{{lines_level}}">{{name}}</td>
  32244. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32245. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32246. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32247. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32248. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32249. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32250. <td class="{{methods_level}} small">{{crap}}</td>
  32251. <td class="{{classes_level}} big">{{classes_bar}}</td>
  32252. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  32253. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  32254. </tr>
  32255. <tr>
  32256. <td class="{{lines_level}}">{{name}}</td>
  32257. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32258. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32259. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32260. <td class="{{branches_level}} big">{{branches_bar}}</td>
  32261. <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
  32262. <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
  32263. <td class="{{paths_level}} big">{{paths_bar}}</td>
  32264. <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
  32265. <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
  32266. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32267. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32268. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32269. <td class="{{methods_level}} small">{{crap}}</td>
  32270. <td class="{{classes_level}} big">{{classes_bar}}</td>
  32271. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  32272. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  32273. </tr>
  32274. <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z"/></svg><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z"/></svg>/*!
  32275. * Bootstrap v4.6.2 (https://getbootstrap.com/)
  32276. * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
  32277. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
  32278. */
  32279. !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),a=i(n);function s(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function l(t,e,n){return e&&s(t.prototype,e),n&&s(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}function r(){return r=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},r.apply(this,arguments)}function u(t,e){return u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},u(t,e)}var f="transitionend";var d={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=o.default(t).css("transition-duration"),n=o.default(t).css("transition-delay"),i=parseFloat(e),a=parseFloat(n);return i||a?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){o.default(t).trigger(f)},supportsTransitionEnd:function(){return Boolean(f)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],a=e[i],s=a&&d.isElement(a)?"element":null===(l=a)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?d.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof o.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=o.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=function(t){var e=this,n=!1;return o.default(this).one(d.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||d.triggerTransitionEnd(e)}),t),this},o.default.event.special[d.TRANSITION_END]={bindType:f,delegateType:f,handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var c="bs.alert",h=o.default.fn.alert,g=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,c),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(c);i||(i=new t(this),n.data(c,i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',g._handleDismiss(new g)),o.default.fn.alert=g._jQueryInterface,o.default.fn.alert.Constructor=g,o.default.fn.alert.noConflict=function(){return o.default.fn.alert=h,g._jQueryInterface};var m="bs.button",p=o.default.fn.button,_="active",v='[data-toggle^="button"]',y='input:not([type="hidden"])',b=".btn",E=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector(y);if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains(_))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass(_)}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains(_)),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(_)),t&&o.default(this._element).toggleClass(_))},e.dispose=function(){o.default.removeData(this._element,m),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),a=i.data(m);a||(a=new t(this),i.data(m,a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.button.data-api",v,(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(b)[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector(y);if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||E._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",v,(function(t){var e=o.default(t.target).closest(b)[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector(y);o.checked||o.hasAttribute("checked")?i.classList.add(_):i.classList.remove(_)}for(var a=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;a<s;a++){var l=t[a];"true"===l.getAttribute("aria-pressed")?l.classList.add(_):l.classList.remove(_)}})),o.default.fn.button=E._jQueryInterface,o.default.fn.button.Constructor=E,o.default.fn.button.noConflict=function(){return o.default.fn.button=p,E._jQueryInterface};var T="carousel",w="bs.carousel",C=o.default.fn[T],S="active",N="next",D="prev",A="slid.bs.carousel",I=".active.carousel-item",k={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},O={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},j={TOUCH:"touch",PEN:"pen"},P=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide(N)},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide(D)},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(I);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one(A,(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?N:D;this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(".bs.carousel"),o.default.removeData(this._element,w),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=r({},k,t),d.typeCheckConfig(T,t,O),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){t.touchDeltaX=e.originalEvent.touches&&e.originalEvent.touches.length>1?0:e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n=t===N,i=t===D,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+(t===D?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(I)),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass(S);var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass(S)}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(I);if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(I),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),f=this._getItemIndex(u),c=Boolean(this._interval);if(t===N?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass(S))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event(A,{relatedTarget:u,direction:a,from:r,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=d.getTransitionDurationFromElement(l);o.default(l).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass(S),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout((function(){return o.default(s._element).trigger(h)}),0)})).emulateTransitionEnd(g)}else o.default(l).removeClass(S),o.default(u).addClass(S),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(w),i=r({},k,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data(w,n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if("undefined"==typeof n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data(w).to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return k}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",P._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var i=o.default(t[e]);P._jQueryInterface.call(i,i.data())}})),o.default.fn[T]=P._jQueryInterface,o.default.fn[T].Constructor=P,o.default.fn[T].noConflict=function(){return o.default.fn[T]=C,P._jQueryInterface};var L="collapse",R="bs.collapse",x=o.default.fn[L],q="show",F="collapse",Q="collapsing",B="collapsed",H="width",U='[data-toggle="collapse"]',M={toggle:!0,parent:""},W={toggle:"boolean",parent:"(string|element)"},V=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll(U)),i=0,o=n.length;i<o;i++){var a=n[i],s=d.getSelectorFromElement(a),l=[].slice.call(document.querySelectorAll(s)).filter((function(e){return e===t}));null!==s&&l.length>0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass(q)?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!(this._isTransitioning||o.default(this._element).hasClass(q)||(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains(F)}))).length&&(e=null),e&&(n=o.default(e).not(this._selector).data(R))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data(R,null));var s=this._getDimension();o.default(this._element).removeClass(F).addClass(Q),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass(B).attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass(Q).addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass(q)){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass(Q).removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a<i;a++){var s=this._triggerArray[a],l=d.getSelectorFromElement(s);null!==l&&(o.default([].slice.call(document.querySelectorAll(l))).hasClass(q)||o.default(s).addClass(B).attr("aria-expanded",!1))}this.setTransitioning(!0),this._element.style[n]="";var r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){t.setTransitioning(!1),o.default(t._element).removeClass(Q).addClass(F).trigger("hidden.bs.collapse")})).emulateTransitionEnd(r)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){o.default.removeData(this._element,R),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=r({},M,t)).toggle=Boolean(t.toggle),d.typeCheckConfig(L,t,W),t},e._getDimension=function(){return o.default(this._element).hasClass(H)?H:"height"},e._getParent=function(){var e,n=this;d.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',a=[].slice.call(e.querySelectorAll(i));return o.default(a).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=o.default(t).hasClass(q);e.length&&o.default(e).toggleClass(B,!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=d.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(R),a=r({},M,n.data(),"object"==typeof e&&e?e:{});if(!i&&a.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(a.toggle=!1),i||(i=new t(this,a),n.data(R,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return M}}]),t}();o.default(document).on("click.bs.collapse.data-api",U,(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=o.default(this),n=d.getSelectorFromElement(this),i=[].slice.call(document.querySelectorAll(n));o.default(i).each((function(){var t=o.default(this),n=t.data(R)?"toggle":e.data();V._jQueryInterface.call(t,n)}))})),o.default.fn[L]=V._jQueryInterface,o.default.fn[L].Constructor=V,o.default.fn[L].noConflict=function(){return o.default.fn[L]=x,V._jQueryInterface};var z="dropdown",K="bs.dropdown",X=o.default.fn[z],Y=new RegExp("38|40|27"),$="disabled",J="show",G="dropdown-menu-right",Z="hide.bs.dropdown",tt="hidden.bs.dropdown",et="click.bs.dropdown.data-api",nt="keydown.bs.dropdown.data-api",it='[data-toggle="dropdown"]',ot=".dropdown-menu",at={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},st={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},lt=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!o.default(this._element).hasClass($)){var e=o.default(this._menu).hasClass(J);t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||o.default(this._element).hasClass($)||o.default(this._menu).hasClass(J))){var n={relatedTarget:this._element},i=o.default.Event("show.bs.dropdown",n),s=t._getParentFromElement(this._element);if(o.default(s).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var l=this._element;"parent"===this._config.reference?l=s:d.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&o.default(s).addClass("position-static"),this._popper=new a.default(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===o.default(s).closest(".navbar-nav").length&&o.default(document.body).children().on("mouseover",null,o.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),o.default(this._menu).toggleClass(J),o.default(s).toggleClass(J).trigger(o.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!o.default(this._element).hasClass($)&&o.default(this._menu).hasClass(J)){var e={relatedTarget:this._element},n=o.default.Event(Z,e),i=t._getParentFromElement(this._element);o.default(i).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),o.default(this._menu).toggleClass(J),o.default(i).toggleClass(J).trigger(o.default.Event(tt,e)))}},e.dispose=function(){o.default.removeData(this._element,K),o.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;o.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=r({},this.constructor.Default,o.default(this._element).data(),t),d.typeCheckConfig(z,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(ot))}return this._menu},e._getPlacement=function(){var t=o.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=o.default(this._menu).hasClass(G)?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":o.default(this._menu).hasClass(G)&&(e="bottom-end"),e},e._detectNavbar=function(){return o.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(K);if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data(K,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll(it)),i=0,a=n.length;i<a;i++){var s=t._getParentFromElement(n[i]),l=o.default(n[i]).data(K),r={relatedTarget:n[i]};if(e&&"click"===e.type&&(r.clickEvent=e),l){var u=l._menu;if(o.default(s).hasClass(J)&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&o.default.contains(s,e.target))){var f=o.default.Event(Z,r);o.default(s).trigger(f),f.isDefaultPrevented()||("ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),n[i].setAttribute("aria-expanded","false"),l._popper&&l._popper.destroy(),o.default(u).removeClass(J),o.default(s).removeClass(J).trigger(o.default.Event(tt,r)))}}}},t._getParentFromElement=function(t){var e,n=d.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||o.default(e.target).closest(ot).length):!Y.test(e.which))&&!this.disabled&&!o.default(this).hasClass($)){var n=t._getParentFromElement(this),i=o.default(n).hasClass(J);if(i||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!i||27===e.which||32===e.which)return 27===e.which&&o.default(n.querySelector(it)).trigger("focus"),void o.default(this).trigger("click");var a=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return o.default(t).is(":visible")}));if(0!==a.length){var s=a.indexOf(e.target);38===e.which&&s>0&&s--,40===e.which&&s<a.length-1&&s++,s<0&&(s=0),a[s].focus()}}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return at}},{key:"DefaultType",get:function(){return st}}]),t}();o.default(document).on(nt,it,lt._dataApiKeydownHandler).on(nt,ot,lt._dataApiKeydownHandler).on(et+" keyup.bs.dropdown.data-api",lt._clearMenus).on(et,it,(function(t){t.preventDefault(),t.stopPropagation(),lt._jQueryInterface.call(o.default(this),"toggle")})).on(et,".dropdown form",(function(t){t.stopPropagation()})),o.default.fn[z]=lt._jQueryInterface,o.default.fn[z].Constructor=lt,o.default.fn[z].noConflict=function(){return o.default.fn[z]=X,lt._jQueryInterface};var rt="bs.modal",ut=o.default.fn.modal,ft="modal-open",dt="fade",ct="show",ht="modal-static",gt="hidden.bs.modal",mt="show.bs.modal",pt="focusin.bs.modal",_t="resize.bs.modal",vt="click.dismiss.bs.modal",yt="keydown.dismiss.bs.modal",bt="mousedown.dismiss.bs.modal",Et=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Tt={backdrop:!0,keyboard:!0,focus:!0,show:!0},wt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Ct=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){var n=o.default.Event(mt,{relatedTarget:t});o.default(this._element).trigger(n),n.isDefaultPrevented()||(this._isShown=!0,o.default(this._element).hasClass(dt)&&(this._isTransitioning=!0),this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),o.default(this._element).on(vt,'[data-dismiss="modal"]',(function(t){return e.hide(t)})),o.default(this._dialog).on(bt,(function(){o.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){o.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=o.default.Event("hide.bs.modal");if(o.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var i=o.default(this._element).hasClass(dt);if(i&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),o.default(document).off(pt),o.default(this._element).removeClass(ct),o.default(this._element).off(vt),o.default(this._dialog).off(bt),i){var a=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(a)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return o.default(t).off(".bs.modal")})),o.default(document).off(pt),o.default.removeData(this._element,rt),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=r({},Tt,t),d.typeCheckConfig("modal",t,wt),t},e._triggerBackdropTransition=function(){var t=this,e=o.default.Event("hidePrevented.bs.modal");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add(ht);var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove(ht),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass(dt),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass(ct),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off(pt).on(pt,(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on(yt,(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off(yt)},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on(_t,(function(e){return t.handleUpdate(e)})):o.default(window).off(_t)},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass(ft),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger(gt)}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass(dt)?dt:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on(vt,(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass(ct),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass(ct);var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass(dt)){var s=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(Et)),n=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(e,n){var i=n.style.paddingRight,a=o.default(n).css("padding-right");o.default(n).data("padding-right",i).css("padding-right",parseFloat(a)+t._scrollbarWidth+"px")})),o.default(n).each((function(e,n){var i=n.style.marginRight,a=o.default(n).css("margin-right");o.default(n).data("margin-right",i).css("margin-right",parseFloat(a)-t._scrollbarWidth+"px")}));var i=document.body.style.paddingRight,a=o.default(document.body).css("padding-right");o.default(document.body).data("padding-right",i).css("padding-right",parseFloat(a)+this._scrollbarWidth+"px")}o.default(document.body).addClass(ft)},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(Et));o.default(t).each((function(t,e){var n=o.default(e).data("padding-right");o.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(t,e){var n=o.default(e).data("margin-right");"undefined"!=typeof n&&o.default(e).css("margin-right",n).removeData("margin-right")}));var n=o.default(document.body).data("padding-right");o.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this).data(rt),a=r({},Tt,o.default(this).data(),"object"==typeof e&&e?e:{});if(i||(i=new t(this,a),o.default(this).data(rt,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else a.show&&i.show(n)}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Tt}}]),t}();o.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,i=d.getSelectorFromElement(this);i&&(e=document.querySelector(i));var a=o.default(e).data(rt)?"toggle":r({},o.default(e).data(),o.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=o.default(e).one(mt,(function(t){t.isDefaultPrevented()||s.one(gt,(function(){o.default(n).is(":visible")&&n.focus()}))}));Ct._jQueryInterface.call(o.default(e),a,this)})),o.default.fn.modal=Ct._jQueryInterface,o.default.fn.modal.Constructor=Ct,o.default.fn.modal.noConflict=function(){return o.default.fn.modal=ut,Ct._jQueryInterface};var St=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Nt=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Dt=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function At(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),a=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=a[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var l=[].slice.call(i.attributes),r=[].concat(e["*"]||[],e[s]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===St.indexOf(n)||Boolean(Nt.test(t.nodeValue)||Dt.test(t.nodeValue));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,a=i.length;o<a;o++)if(i[o].test(n))return!0;return!1})(t,r)||i.removeAttribute(t.nodeName)}))},l=0,r=a.length;l<r;l++)s(l);return i.body.innerHTML}var It="tooltip",kt="bs.tooltip",Ot=o.default.fn.tooltip,jt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Pt=["sanitize","whiteList","sanitizeFn"],Lt="fade",Rt="show",xt="show",qt="out",Ft="hover",Qt="focus",Bt={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Ht={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ut={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Mt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Wt=function(){function t(t,e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass(Rt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=d.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass(Lt);var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var f=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass(Rt),o.default(s).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),e===qt&&t._leave(null,t)};if(o.default(this.tip).hasClass(Lt)){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){e._hoverState!==xt&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass(Rt),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass(Lt)){var s=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=At(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return Bt[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n=e===Ft?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i=e===Ft?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Qt:Ft]=!0),o.default(e.getTipElement()).hasClass(Rt)||e._hoverState===xt?e._hoverState=xt:(clearTimeout(e._timeout),e._hoverState=xt,e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){e._hoverState===xt&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Qt:Ft]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=qt,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){e._hoverState===qt&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Pt.indexOf(t)&&delete e[t]})),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(It,t,this.constructor.DefaultType),t.sanitize&&(t.template=At(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(jt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass(Lt),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(kt),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data(kt,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Ht}},{key:"NAME",get:function(){return It}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Mt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Ut}}]),t}();o.default.fn.tooltip=Wt._jQueryInterface,o.default.fn.tooltip.Constructor=Wt,o.default.fn.tooltip.noConflict=function(){return o.default.fn.tooltip=Ot,Wt._jQueryInterface};var Vt="bs.popover",zt=o.default.fn.popover,Kt=new RegExp("(^|\\s)bs-popover\\S+","g"),Xt=r({},Wt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Yt=r({},Wt.DefaultType,{content:"(string|element|function)"}),$t={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Jt=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,u(e,n);var a=i.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(Kt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data(Vt),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data(Vt,e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},l(i,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Xt}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return Vt}},{key:"Event",get:function(){return $t}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Yt}}]),i}(Wt);o.default.fn.popover=Jt._jQueryInterface,o.default.fn.popover.Constructor=Jt,o.default.fn.popover.noConflict=function(){return o.default.fn.popover=zt,Jt._jQueryInterface};var Gt="scrollspy",Zt="bs.scrollspy",te=o.default.fn[Gt],ee="active",ne="position",ie=".nav, .list-group",oe={offset:10,method:"auto",target:""},ae={offset:"number",method:"string",target:"(string|element)"},se=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":ne,n="auto"===this._config.method?e:this._config.method,i=n===ne?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,a=d.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)return[o.default(e)[n]().top+i,a]}return null})).filter(Boolean).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,Zt),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=r({},oe,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(Gt),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(Gt,t,ae),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=o.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass(ee),n.addClass(ee)):(n.addClass(ee),n.parents(ie).prev(".nav-link, .list-group-item").addClass(ee),n.parents(ie).prev(".nav-item").children(".nav-link").addClass(ee)),o.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains(ee)})).forEach((function(t){return t.classList.remove(ee)}))},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(Zt);if(n||(n=new t(this,"object"==typeof e&&e),o.default(this).data(Zt,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return oe}}]),t}();o.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=o.default(t[e]);se._jQueryInterface.call(n,n.data())}})),o.default.fn[Gt]=se._jQueryInterface,o.default.fn[Gt].Constructor=se,o.default.fn[Gt].noConflict=function(){return o.default.fn[Gt]=te,se._jQueryInterface};var le="bs.tab",re=o.default.fn.tab,ue="active",fe="fade",de="show",ce=".active",he="> li > .active",ge=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass(ue)||o.default(this._element).hasClass("disabled")||this._element.hasAttribute("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=d.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?he:ce;n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,le),this._element=null},e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(ce):o.default(e).find(he))[0],s=n&&a&&o.default(a).hasClass(fe),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=d.getTransitionDurationFromElement(a);o.default(a).removeClass(de).one(d.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass(ue);var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass(ue),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}o.default(t).addClass(ue),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains(fe)&&t.classList.add(de);var a=t.parentNode;if(a&&"LI"===a.nodeName&&(a=a.parentNode),a&&o.default(a).hasClass("dropdown-menu")){var s=o.default(t).closest(".dropdown")[0];if(s){var l=[].slice.call(s.querySelectorAll(".dropdown-toggle"));o.default(l).addClass(ue)}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(le);if(i||(i=new t(this),n.data(le,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ge._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=ge._jQueryInterface,o.default.fn.tab.Constructor=ge,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=re,ge._jQueryInterface};var me="bs.toast",pe=o.default.fn.toast,_e="hide",ve="show",ye="showing",be="click.dismiss.bs.toast",Ee={animation:!0,autohide:!0,delay:500},Te={animation:"boolean",autohide:"boolean",delay:"number"},we=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove(ye),t._element.classList.add(ve),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove(_e),d.reflow(this._element),this._element.classList.add(ye),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains(ve)){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains(ve)&&this._element.classList.remove(ve),o.default(this._element).off(be),o.default.removeData(this._element,me),this._element=null,this._config=null},e._getConfig=function(t){return t=r({},Ee,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on(be,'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add(_e),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove(ve),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(me);if(i||(i=new t(this,"object"==typeof e&&e),n.data(me,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"DefaultType",get:function(){return Te}},{key:"Default",get:function(){return Ee}}]),t}();o.default.fn.toast=we._jQueryInterface,o.default.fn.toast.Constructor=we,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=pe,we._jQueryInterface},t.Alert=g,t.Button=E,t.Carousel=P,t.Collapse=V,t.Dropdown=lt,t.Modal=Ct,t.Popover=Jt,t.Scrollspy=se,t.Tab=ge,t.Toast=we,t.Tooltip=Wt,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})}));
  32280. //# sourceMappingURL=bootstrap.min.js.map!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){
  32281. r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){
  32282. return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
  32283. shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
  32284. if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); $(function() {
  32285. var $window = $(window)
  32286. , $top_link = $('#toplink')
  32287. , $body = $('body, html')
  32288. , offset = $('#code').offset().top
  32289. , hidePopover = function ($target) {
  32290. $target.data('popover-hover', false);
  32291. setTimeout(function () {
  32292. if (!$target.data('popover-hover')) {
  32293. $target.popover('hide');
  32294. }
  32295. }, 300);
  32296. };
  32297. $top_link.hide().click(function(event) {
  32298. event.preventDefault();
  32299. $body.animate({scrollTop:0}, 800);
  32300. });
  32301. $window.scroll(function() {
  32302. if($window.scrollTop() > offset) {
  32303. $top_link.fadeIn();
  32304. } else {
  32305. $top_link.fadeOut();
  32306. }
  32307. }).scroll();
  32308. $('.popin')
  32309. .popover({trigger: 'manual'})
  32310. .on({
  32311. 'mouseenter.popover': function () {
  32312. var $target = $(this);
  32313. var $container = $target.children().first();
  32314. $target.data('popover-hover', true);
  32315. // popover already displayed
  32316. if ($target.next('.popover').length) {
  32317. return;
  32318. }
  32319. // show the popover
  32320. $container.popover('show');
  32321. // register mouse events on the popover
  32322. $target.next('.popover:not(.popover-initialized)')
  32323. .on({
  32324. 'mouseenter': function () {
  32325. $target.data('popover-hover', true);
  32326. },
  32327. 'mouseleave': function () {
  32328. hidePopover($container);
  32329. }
  32330. })
  32331. .addClass('popover-initialized');
  32332. },
  32333. 'mouseleave.popover': function () {
  32334. hidePopover($(this).children().first());
  32335. }
  32336. });
  32337. });
  32338. /*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
  32339. !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:v}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,y,s,c,v,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),v(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace($," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,y){var v="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===y?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=v!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(v){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=y)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ye(function(){return[0]}),last:ye(function(e,t){return[t-1]}),eq:ye(function(e,t,n){return[n<0?n+t:n]}),even:ye(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ye(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ye(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ye(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,y,v,e){return y&&!y[S]&&(y=Ce(y)),v&&!v[S]&&(v=Ce(v,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?v||(e?d:l||y)?[]:t:f;if(g&&g(f,p,n,r),y){i=Te(p,u),y(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(v||d){if(v){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);v(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=v?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),v?v(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,y,v,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(y=o,m=0<(v=i).length,x=0<y.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=y[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=v[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+v.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ve(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function $(){E.removeEventListener("DOMContentLoaded",$),C.removeEventListener("load",$),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",$),C.addEventListener("load",$));var B=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)B(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):B(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",v.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,v.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=y.events)||(u=y.events=Object.create(null)),(a=y.handle)||(a=y.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.hasData(e)&&Y.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||S.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(t,e){S.event.special[t]={setup:function(){return Se(this,t,Ce),!1},trigger:function(){return Se(this,t),!0},_default:function(e){return Y.get(e.target,t)},delegateType:e}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!v.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ye(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ye(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ye(r)),r.parentNode&&(n&&ie(r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ye(c),r=0,i=(o=ye(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ye(e),a=a||ye(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ye(c,"script")).length&&ve(a,!f&&ye(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return B(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return B(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ye(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=/^--/,Me=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Ie=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},We=new RegExp(ne.join("|"),"i"),Fe="[\\x20\\t\\r\\n\\f]",$e=new RegExp("^"+Fe+"+|((?:^|[^\\\\])(?:\\\\.)*)"+Fe+"+$","g");function Be(e,t,n){var r,i,o,a,s=Re.test(t),u=e.style;return(n=n||Me(e))&&(a=n.getPropertyValue(t)||n[t],s&&(a=a.replace($e,"$1")),""!==a||ie(e)||(a=S.style(e,t)),!v.pixelBoxStyles()&&Pe.test(a)&&We.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(v,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var ze=["Webkit","Moz","ms"],Ue=E.createElement("div").style,Xe={};function Ve(e){var t=S.cssProps[e]||Xe[e];return t||(e in Ue?e:Xe[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=ze.length;while(n--)if((e=ze[n]+t)in Ue)return e}(e)||e)}var Ge=/^(none|table(?!-c[ea]).+)/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Me(e),i=(!v.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&i||!v.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Re.test(t),l=e.style;if(u||(t=Ve(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Re.test(t)||(t=Ve(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ge.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):Ie(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Me(e),o=!v.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=_e(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-Ie(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return B(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Me(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Ve(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(y?"hidden"in y&&(g=y.hidden):y=Y.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",v.checkOn=""!==rt.value,v.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",v.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return B(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function yt(e){return(e.match(P)||[]).join(" ")}function vt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return B(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),v.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){S(this).addClass(t.call(this,e,vt(this)))}):(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=yt(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){S(this).removeClass(t.call(this,e,vt(this)))}):arguments.length?(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=yt(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"===a||Array.isArray(t);return m(t)?this.each(function(e){S(this).toggleClass(t.call(this,e,vt(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=mt(t),this.each(function(){if(s)for(o=S(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!==a||((r=vt(this))&&Y.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":Y.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+yt(vt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:yt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},v.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),v.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=y.call(e,"type")?e.type:e,h=y.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),v.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function jt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):jt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)jt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var Dt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function $t(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Bt(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Bt(Bt(e,S.ajaxSettings),t):Bt(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,y=S.ajaxSetup({},t),v=y.context||y,m=y.context&&(v.nodeType||v.jquery)?S(v):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=y.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(y.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),y.url=((e||y.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),y.type=t.method||t.type||y.method||y.type,y.dataTypes=(y.dataType||"*").toLowerCase().match(P)||[""],null==y.crossDomain){r=E.createElement("a");try{r.href=y.url,r.href=r.href,y.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){y.crossDomain=!0}}if(y.data&&y.processData&&"string"!=typeof y.data&&(y.data=S.param(y.data,y.traditional)),$t(Rt,y,t,T),h)return T;for(i in(g=S.event&&y.global)&&0==S.active++&&S.event.trigger("ajaxStart"),y.type=y.type.toUpperCase(),y.hasContent=!Ot.test(y.type),f=y.url.replace(qt,""),y.hasContent?y.data&&y.processData&&0===(y.contentType||"").indexOf("application/x-www-form-urlencoded")&&(y.data=y.data.replace(Dt,"+")):(o=y.url.slice(f.length),y.data&&(y.processData||"string"==typeof y.data)&&(f+=(Et.test(f)?"&":"?")+y.data,delete y.data),!1===y.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),y.url=f+o),y.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(y.data&&y.hasContent&&!1!==y.contentType||t.contentType)&&T.setRequestHeader("Content-Type",y.contentType),T.setRequestHeader("Accept",y.dataTypes[0]&&y.accepts[y.dataTypes[0]]?y.accepts[y.dataTypes[0]]+("*"!==y.dataTypes[0]?", "+It+"; q=0.01":""):y.accepts["*"]),y.headers)T.setRequestHeader(i,y.headers[i]);if(y.beforeSend&&(!1===y.beforeSend.call(v,T,y)||h))return T.abort();if(u="abort",b.add(y.complete),T.done(y.success),T.fail(y.error),c=$t(Mt,y,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,y]),h)return T;y.async&&0<y.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},y.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(y,T,n)),!i&&-1<S.inArray("script",y.dataTypes)&&S.inArray("json",y.dataTypes)<0&&(y.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(y,s,T,i),i?(y.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===y.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(v,[o,l,T]):x.rejectWith(v,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,y,i?o:a]),b.fireWith(v,[T,l]),g&&(m.trigger("ajaxComplete",[T,y]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();v.cors=!!zt&&"withCredentials"in zt,v.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(v.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=yt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
  32340. /* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-15 */
  32341. !function(){var a={};a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.logs={},a.dom={},a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(a,b){console&&console.warn&&console.warn("nvd3 warning: `"+a+"` has been deprecated. ",b||"")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start();var c=function(){for(var d,e,f=0;b>f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+="<div class='footer'>"+a.footer+"</div>"),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)<E[0]||d(a)>E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g");
  32342. x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f);
  32343. var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&C<B.length;)E[C]=B[C],D+=B[C++];for(0===C&&(C=1);D>p&&C>1;){E=[],C--;for(var F=0;F<B.length;F++)B[F]>(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,d<c.left+c.right+J+a&&(L=J=5,K+=A),L+=a,L>M&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&E<D.length;)F[E]=D[E],C+=D[E++];for(0===E&&(E=1);C>g&&E>1;){F=[],E--;for(var G=0;G<D.length;G++)D[G]>(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,d<c.left+c.right+K+a&&(M=K=5,L+=x),M+=a,M>N&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D]
  32344. }if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();
  32345. var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left
  32346. }},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;M<b[0].length;M++)I.push(K),J.push(L);else I=z.map(function(a){return(a.outer-a.outer/5)*H}),J=z.map(function(a){return(a.inner-a.inner/5)*H}),y=d3.min(z.map(function(a){return a.inner-a.inner/5}));a.utils.initSVG(i);var N=i.selectAll(".nv-wrap.nv-pie").data(b),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+h),P=O.append("g"),Q=N.select("g"),R=P.append("g").attr("class","nv-pie");P.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+c.left+","+c.top+")"),Q.select(".nv-pie").attr("transform","translate("+F/2+","+G/2+")"),Q.select(".nv-pieLabels").attr("transform","translate("+F/2+","+G/2+")"),i.on("click",function(a,b){A.chartClick({data:a,index:b,pos:d3.event,id:h})}),B=[],C=[];for(var M=0;M<b[0].length;M++){var S=d3.svg.arc().outerRadius(I[M]),T=d3.svg.arc().outerRadius(I[M]+5);u!==!1&&(S.startAngle(u),T.startAngle(u)),w!==!1&&(S.endAngle(w),T.endAngle(w)),p&&(S.innerRadius(J[M]),T.innerRadius(J[M])),S.cornerRadius&&x&&(S.cornerRadius(x),T.cornerRadius(x)),B.push(S),C.push(T)}var U=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:g(a)});U.padAngle&&v&&U.padAngle(v),p&&q&&(R.append("text").attr("class","nv-pie-title"),N.select(".nv-pie-title").style("text-anchor","middle").text(function(){return q}).style("font-size",Math.min(F,G)*y*2/(q.length+2)+"px").attr("dy","0.35em").attr("transform",function(){return"translate(0, "+s+")"}));var V=N.select(".nv-pie").selectAll(".nv-slice").data(U),W=N.select(".nv-pieLabels").selectAll(".nv-label").data(U);V.exit().remove(),W.exit().remove();var X=V.enter().append("g");X.attr("class","nv-slice"),X.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),r&&d3.select(this).select("path").transition().duration(70).attr("d",C[b]),A.elementMouseover({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),r&&d3.select(this).select("path").transition().duration(50).attr("d",B[b]),A.elementMouseout({data:a.data,index:b})}),X.on("mousemove",function(a,b){A.elementMousemove({data:a.data,index:b})}),X.on("click",function(a,b){A.elementClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("dblclick",function(a,b){A.elementDblClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),V.attr("fill",function(a,b){return j(a.data,b)}),V.attr("stroke",function(a,b){return j(a.data,b)});X.append("path").each(function(a){this._current=a});if(V.select("path").transition().attr("d",function(a,b){return B[b](a)}).attrTween("d",E),l){for(var Y=[],M=0;M<b[0].length;M++)Y.push(B[M]),m?p&&(Y[M]=d3.svg.arc().outerRadius(B[M].outerRadius()),u!==!1&&Y[M].startAngle(u),w!==!1&&Y[M].endAngle(w)):p||Y[M].innerRadius(0);W.enter().append("g").classed("nv-label",!0).each(function(a){var b=d3.select(this);b.attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}return a.outerRadius=H+10,a.innerRadius=H+15,"translate("+Y[b].centroid(a)+")"}),b.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),b.append("text").style("text-anchor",t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var Z={},$=14,_=140,ab=function(a){return Math.floor(a[0]/_)*_+","+Math.floor(a[1]/$)*$};W.watchTransition(D,"pie labels").attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}a.outerRadius=H+10,a.innerRadius=H+15;var d=Y[b].centroid(a);if(a.value){var e=ab(d);Z[e]&&(d[1]-=$),Z[ab(d)]=!0}return"translate("+d+")"}),W.select(".nv-label text").style("text-anchor",function(a){return t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle"}).text(function(a,b){var c=(a.endAngle-a.startAngle)/(2*Math.PI),d="";if(!a.value||o>c)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b)
  32347. }},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(p,Math.round(c.invert(b)))],q()}}var s=d3.select(this);a.utils.initSVG(s);var t=a.utils.availableWidth(g,s,f),u=a.utils.availableHeight(h,s,f);if(b.update=function(){s.call(b)},b.container=this,!p||!p.length)return a.utils.noData(b,s),b;s.selectAll(".nv-noData").remove();var v=e.y()(p[p.length-1],p.length-1);c=e.xScale(),d=e.yScale();var w=s.selectAll("g.nv-wrap.nv-sparklineplus").data([p]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),y=x.append("g"),z=w.select("g");y.append("g").attr("class","nv-sparklineWrap"),y.append("g").attr("class","nv-valueWrap"),y.append("g").attr("class","nv-hoverArea"),w.attr("transform","translate("+f.left+","+f.top+")");var A=z.select(".nv-sparklineWrap");if(e.width(t).height(u),A.call(e),m){var B=z.select(".nv-valueWrap"),C=B.selectAll(".nv-currentValue").data([v]);C.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),C.attr("x",t+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(p[p.length-1],p.length-1)).text(l(v))}y.select(".nv-hoverArea").append("rect").on("mousemove",r).on("click",function(){j=!j}).on("mouseout",function(){i=[],q()}),z.select(".nv-hoverArea rect").attr("transform",function(){return"translate("+-f.left+","+-f.top+")"}).attr("width",t+f.left+f.right).attr("height",u+f.top)}),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p=null;return b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showLastValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(m){return u.reset(),u.models(r),m.each(function(m){var s=f-e.left-e.right,v=g-e.top-e.bottom;j=d3.select(this),a.utils.initSVG(j),c=r.xScale(),d=r.yScale();var w=m;m.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var x=m.filter(function(a){return!a.disabled});m=d3.layout.stack().order(o).offset(n).values(function(a){return a.values}).x(k).y(l).out(function(a,b,c){a.display={y:c,y0:b}})(x);var y=j.selectAll("g.nv-wrap.nv-stackedarea").data([m]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),A=z.append("defs"),B=z.append("g"),C=y.select("g");B.append("g").attr("class","nv-areaWrap"),B.append("g").attr("class","nv-scatterWrap"),y.attr("transform","translate("+e.left+","+e.top+")"),0==r.forceY().length&&r.forceY().push(0),r.width(s).height(v).x(k).y(function(a){return a.display.y+a.display.y0}).forceY([0]).color(m.map(function(a){return a.color||h(a,a.seriesIndex)}));var D=C.select(".nv-scatterWrap").datum(m);D.call(r),A.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),y.select("#nv-edge-clip-"+i+" rect").attr("width",s).attr("height",v),C.attr("clip-path",q?"url(#nv-edge-clip-"+i+")":"");var E=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(p),F=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),G=C.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});G.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a){return F(a.values,a.seriesIndex)}).on("mouseover",function(a){d3.select(this).classed("hover",!0),t.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a){d3.select(this).classed("hover",!1),t.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a){d3.select(this).classed("hover",!1),t.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),G.exit().remove(),G.style("fill",function(a){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a){return a.color||h(a,a.seriesIndex)}),G.watchTransition(u,"stackedArea path").attr("d",function(a,b){return E(a.values,b)}),r.dispatch.on("elementMouseover.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),r.dispatch.on("elementMouseout.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=[];for(c=0;f>c;++c){for(b=0,d=0;b<w.length;b++)d+=l(w[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}();/*
  32348. Copyright (C) Federico Zivolo 2020
  32349. Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
  32350. */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'])+parseFloat(e['border'+n+'Width'])}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth),c=parseFloat(m.borderLeftWidth);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop),y=parseFloat(m.marginLeft);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f]),E=parseFloat(w['border'+f+'Width']),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
  32351. //# sourceMappingURL=popper.min.js.map
  32352. <tr class="{{class}} d-flex"><td {{popover}} class="col-1 text-right"><a id="{{lineNumber}}" href="#{{lineNumber}}">{{lineNumber}}</a></td><td class="col-11 codeLine">{{lineContent}}</td></tr>
  32353. <table id="code" class="table table-borderless table-condensed">
  32354. <tbody>
  32355. {{lines}}
  32356. </tbody>
  32357. </table>
  32358. <tr>
  32359. <td class="{{lines_level}}">{{name}}</td>
  32360. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32361. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32362. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32363. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32364. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32365. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32366. <td class="{{methods_level}} small">{{crap}}</td>
  32367. <td class="{{methods_level}}" colspan="3"></td>
  32368. </tr>
  32369. <tr>
  32370. <td class="{{lines_level}}">{{name}}</td>
  32371. <td class="{{lines_level}} big">{{lines_bar}}</td>
  32372. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  32373. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  32374. <td class="{{branches_level}} big">{{branches_bar}}</td>
  32375. <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
  32376. <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
  32377. <td class="{{paths_level}} big">{{paths_bar}}</td>
  32378. <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
  32379. <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
  32380. <td class="{{methods_level}} big">{{methods_bar}}</td>
  32381. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  32382. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  32383. <td class="{{methods_level}} small">{{crap}}</td>
  32384. <td class="{{methods_level}}" colspan="3"></td>
  32385. </tr>
  32386. <hr/>
  32387. <h4>Paths</h4>
  32388. <p>
  32389. Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
  32390. necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
  32391. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an <code>if</code> statement
  32392. <i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
  32393. </p>
  32394. {{paths}}
  32395. <?php
  32396. declare (strict_types=1);
  32397. /*
  32398. * This file is part of phpunit/php-code-coverage.
  32399. *
  32400. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32401. *
  32402. * For the full copyright and license information, please view the LICENSE
  32403. * file that was distributed with this source code.
  32404. */
  32405. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  32406. use function dirname;
  32407. use function file_put_contents;
  32408. use function serialize;
  32409. use function str_contains;
  32410. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  32411. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
  32412. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  32413. final class PHP
  32414. {
  32415. public function process(CodeCoverage $coverage, ?string $target = null): string
  32416. {
  32417. $coverage->clearCache();
  32418. $buffer = "<?php\nreturn \\unserialize(<<<'END_OF_COVERAGE_SERIALIZATION'" . \PHP_EOL . serialize($coverage) . \PHP_EOL . 'END_OF_COVERAGE_SERIALIZATION' . \PHP_EOL . ');';
  32419. if ($target !== null) {
  32420. if (!str_contains($target, '://')) {
  32421. Filesystem::createDirectory(dirname($target));
  32422. }
  32423. if (@file_put_contents($target, $buffer) === \false) {
  32424. throw new WriteOperationFailedException($target);
  32425. }
  32426. }
  32427. return $buffer;
  32428. }
  32429. }
  32430. <?php
  32431. declare (strict_types=1);
  32432. /*
  32433. * This file is part of phpunit/php-code-coverage.
  32434. *
  32435. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32436. *
  32437. * For the full copyright and license information, please view the LICENSE
  32438. * file that was distributed with this source code.
  32439. */
  32440. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  32441. use const PHP_EOL;
  32442. use function array_map;
  32443. use function date;
  32444. use function ksort;
  32445. use function max;
  32446. use function sprintf;
  32447. use function str_pad;
  32448. use function strlen;
  32449. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  32450. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
  32451. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
  32452. final class Text
  32453. {
  32454. /**
  32455. * @var string
  32456. */
  32457. private const COLOR_GREEN = "\x1b[30;42m";
  32458. /**
  32459. * @var string
  32460. */
  32461. private const COLOR_YELLOW = "\x1b[30;43m";
  32462. /**
  32463. * @var string
  32464. */
  32465. private const COLOR_RED = "\x1b[37;41m";
  32466. /**
  32467. * @var string
  32468. */
  32469. private const COLOR_HEADER = "\x1b[1;37;40m";
  32470. /**
  32471. * @var string
  32472. */
  32473. private const COLOR_RESET = "\x1b[0m";
  32474. private readonly Thresholds $thresholds;
  32475. private readonly bool $showUncoveredFiles;
  32476. private readonly bool $showOnlySummary;
  32477. public function __construct(Thresholds $thresholds, bool $showUncoveredFiles = \false, bool $showOnlySummary = \false)
  32478. {
  32479. $this->thresholds = $thresholds;
  32480. $this->showUncoveredFiles = $showUncoveredFiles;
  32481. $this->showOnlySummary = $showOnlySummary;
  32482. }
  32483. public function process(CodeCoverage $coverage, bool $showColors = \false): string
  32484. {
  32485. $hasBranchCoverage = !empty($coverage->getData(\true)->functionCoverage());
  32486. $output = PHP_EOL . PHP_EOL;
  32487. $report = $coverage->getReport();
  32488. $colors = ['header' => '', 'classes' => '', 'methods' => '', 'lines' => '', 'branches' => '', 'paths' => '', 'reset' => ''];
  32489. if ($showColors) {
  32490. $colors['classes'] = $this->coverageColor($report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits());
  32491. $colors['methods'] = $this->coverageColor($report->numberOfTestedMethods(), $report->numberOfMethods());
  32492. $colors['lines'] = $this->coverageColor($report->numberOfExecutedLines(), $report->numberOfExecutableLines());
  32493. $colors['branches'] = $this->coverageColor($report->numberOfExecutedBranches(), $report->numberOfExecutableBranches());
  32494. $colors['paths'] = $this->coverageColor($report->numberOfExecutedPaths(), $report->numberOfExecutablePaths());
  32495. $colors['reset'] = self::COLOR_RESET;
  32496. $colors['header'] = self::COLOR_HEADER;
  32497. }
  32498. $classes = sprintf(' Classes: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits())->asString(), $report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits());
  32499. $methods = sprintf(' Methods: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfTestedMethods(), $report->numberOfMethods())->asString(), $report->numberOfTestedMethods(), $report->numberOfMethods());
  32500. $paths = '';
  32501. $branches = '';
  32502. if ($hasBranchCoverage) {
  32503. $paths = sprintf(' Paths: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedPaths(), $report->numberOfExecutablePaths())->asString(), $report->numberOfExecutedPaths(), $report->numberOfExecutablePaths());
  32504. $branches = sprintf(' Branches: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedBranches(), $report->numberOfExecutableBranches())->asString(), $report->numberOfExecutedBranches(), $report->numberOfExecutableBranches());
  32505. }
  32506. $lines = sprintf(' Lines: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedLines(), $report->numberOfExecutableLines())->asString(), $report->numberOfExecutedLines(), $report->numberOfExecutableLines());
  32507. $padding = max(array_map('strlen', [$classes, $methods, $lines]));
  32508. if ($this->showOnlySummary) {
  32509. $title = 'Code Coverage Report Summary:';
  32510. $padding = max($padding, strlen($title));
  32511. $output .= $this->format($colors['header'], $padding, $title);
  32512. } else {
  32513. $date = date(' Y-m-d H:i:s');
  32514. $title = 'Code Coverage Report:';
  32515. $output .= $this->format($colors['header'], $padding, $title);
  32516. $output .= $this->format($colors['header'], $padding, $date);
  32517. $output .= $this->format($colors['header'], $padding, '');
  32518. $output .= $this->format($colors['header'], $padding, ' Summary:');
  32519. }
  32520. $output .= $this->format($colors['classes'], $padding, $classes);
  32521. $output .= $this->format($colors['methods'], $padding, $methods);
  32522. if ($hasBranchCoverage) {
  32523. $output .= $this->format($colors['paths'], $padding, $paths);
  32524. $output .= $this->format($colors['branches'], $padding, $branches);
  32525. }
  32526. $output .= $this->format($colors['lines'], $padding, $lines);
  32527. if ($this->showOnlySummary) {
  32528. return $output . PHP_EOL;
  32529. }
  32530. $classCoverage = [];
  32531. foreach ($report as $item) {
  32532. if (!$item instanceof File) {
  32533. continue;
  32534. }
  32535. $classes = $item->classesAndTraits();
  32536. foreach ($classes as $className => $class) {
  32537. $classExecutableLines = 0;
  32538. $classExecutedLines = 0;
  32539. $classExecutableBranches = 0;
  32540. $classExecutedBranches = 0;
  32541. $classExecutablePaths = 0;
  32542. $classExecutedPaths = 0;
  32543. $coveredMethods = 0;
  32544. $classMethods = 0;
  32545. foreach ($class['methods'] as $method) {
  32546. if ($method['executableLines'] == 0) {
  32547. continue;
  32548. }
  32549. $classMethods++;
  32550. $classExecutableLines += $method['executableLines'];
  32551. $classExecutedLines += $method['executedLines'];
  32552. $classExecutableBranches += $method['executableBranches'];
  32553. $classExecutedBranches += $method['executedBranches'];
  32554. $classExecutablePaths += $method['executablePaths'];
  32555. $classExecutedPaths += $method['executedPaths'];
  32556. if ($method['coverage'] == 100) {
  32557. $coveredMethods++;
  32558. }
  32559. }
  32560. $classCoverage[$className] = ['namespace' => $class['namespace'], 'className' => $className, 'methodsCovered' => $coveredMethods, 'methodCount' => $classMethods, 'statementsCovered' => $classExecutedLines, 'statementCount' => $classExecutableLines, 'branchesCovered' => $classExecutedBranches, 'branchesCount' => $classExecutableBranches, 'pathsCovered' => $classExecutedPaths, 'pathsCount' => $classExecutablePaths];
  32561. }
  32562. }
  32563. ksort($classCoverage);
  32564. $methodColor = '';
  32565. $pathsColor = '';
  32566. $branchesColor = '';
  32567. $linesColor = '';
  32568. $resetColor = '';
  32569. foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
  32570. if ($this->showUncoveredFiles || $classInfo['statementsCovered'] != 0) {
  32571. if ($showColors) {
  32572. $methodColor = $this->coverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
  32573. $pathsColor = $this->coverageColor($classInfo['pathsCovered'], $classInfo['pathsCount']);
  32574. $branchesColor = $this->coverageColor($classInfo['branchesCovered'], $classInfo['branchesCount']);
  32575. $linesColor = $this->coverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
  32576. $resetColor = $colors['reset'];
  32577. }
  32578. $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' ';
  32579. if ($hasBranchCoverage) {
  32580. $output .= ' ' . $pathsColor . 'Paths: ' . $this->printCoverageCounts($classInfo['pathsCovered'], $classInfo['pathsCount'], 3) . $resetColor . ' ' . ' ' . $branchesColor . 'Branches: ' . $this->printCoverageCounts($classInfo['branchesCovered'], $classInfo['branchesCount'], 3) . $resetColor . ' ';
  32581. }
  32582. $output .= ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor;
  32583. }
  32584. }
  32585. return $output . PHP_EOL;
  32586. }
  32587. private function coverageColor(int $numberOfCoveredElements, int $totalNumberOfElements): string
  32588. {
  32589. $coverage = Percentage::fromFractionAndTotal($numberOfCoveredElements, $totalNumberOfElements);
  32590. if ($coverage->asFloat() >= $this->thresholds->highLowerBound()) {
  32591. return self::COLOR_GREEN;
  32592. }
  32593. if ($coverage->asFloat() > $this->thresholds->lowUpperBound()) {
  32594. return self::COLOR_YELLOW;
  32595. }
  32596. return self::COLOR_RED;
  32597. }
  32598. private function printCoverageCounts(int $numberOfCoveredElements, int $totalNumberOfElements, int $precision): string
  32599. {
  32600. $format = '%' . $precision . 's';
  32601. return Percentage::fromFractionAndTotal($numberOfCoveredElements, $totalNumberOfElements)->asFixedWidthString() . ' (' . sprintf($format, $numberOfCoveredElements) . '/' . sprintf($format, $totalNumberOfElements) . ')';
  32602. }
  32603. private function format(string $color, int $padding, false|string $string): string
  32604. {
  32605. if ($color === '') {
  32606. return (string) $string . PHP_EOL;
  32607. }
  32608. return $color . str_pad((string) $string, $padding) . self::COLOR_RESET . PHP_EOL;
  32609. }
  32610. }
  32611. <?php
  32612. declare (strict_types=1);
  32613. /*
  32614. * This file is part of phpunit/php-code-coverage.
  32615. *
  32616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32617. *
  32618. * For the full copyright and license information, please view the LICENSE
  32619. * file that was distributed with this source code.
  32620. */
  32621. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
  32622. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
  32623. /**
  32624. * @psalm-immutable
  32625. */
  32626. final class Thresholds
  32627. {
  32628. private readonly int $lowUpperBound;
  32629. private readonly int $highLowerBound;
  32630. public static function default(): self
  32631. {
  32632. return new self(50, 90);
  32633. }
  32634. /**
  32635. * @throws InvalidArgumentException
  32636. */
  32637. public static function from(int $lowUpperBound, int $highLowerBound): self
  32638. {
  32639. if ($lowUpperBound > $highLowerBound) {
  32640. throw new InvalidArgumentException('$lowUpperBound must not be larger than $highLowerBound');
  32641. }
  32642. return new self($lowUpperBound, $highLowerBound);
  32643. }
  32644. private function __construct(int $lowUpperBound, int $highLowerBound)
  32645. {
  32646. $this->lowUpperBound = $lowUpperBound;
  32647. $this->highLowerBound = $highLowerBound;
  32648. }
  32649. public function lowUpperBound(): int
  32650. {
  32651. return $this->lowUpperBound;
  32652. }
  32653. public function highLowerBound(): int
  32654. {
  32655. return $this->highLowerBound;
  32656. }
  32657. }
  32658. <?php
  32659. declare (strict_types=1);
  32660. /*
  32661. * This file is part of phpunit/php-code-coverage.
  32662. *
  32663. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32664. *
  32665. * For the full copyright and license information, please view the LICENSE
  32666. * file that was distributed with this source code.
  32667. */
  32668. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  32669. use function phpversion;
  32670. use DateTimeImmutable;
  32671. use DOMElement;
  32672. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  32673. /**
  32674. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  32675. */
  32676. final class BuildInformation
  32677. {
  32678. private readonly DOMElement $contextNode;
  32679. public function __construct(DOMElement $contextNode)
  32680. {
  32681. $this->contextNode = $contextNode;
  32682. }
  32683. public function setRuntimeInformation(Runtime $runtime): void
  32684. {
  32685. $runtimeNode = $this->nodeByName('runtime');
  32686. $runtimeNode->setAttribute('name', $runtime->getName());
  32687. $runtimeNode->setAttribute('version', $runtime->getVersion());
  32688. $runtimeNode->setAttribute('url', $runtime->getVendorUrl());
  32689. $driverNode = $this->nodeByName('driver');
  32690. if ($runtime->hasXdebug()) {
  32691. $driverNode->setAttribute('name', 'xdebug');
  32692. $driverNode->setAttribute('version', phpversion('xdebug'));
  32693. }
  32694. if ($runtime->hasPCOV()) {
  32695. $driverNode->setAttribute('name', 'pcov');
  32696. $driverNode->setAttribute('version', phpversion('pcov'));
  32697. }
  32698. }
  32699. public function setBuildTime(DateTimeImmutable $date): void
  32700. {
  32701. $this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
  32702. }
  32703. public function setGeneratorVersions(string $phpUnitVersion, string $coverageVersion): void
  32704. {
  32705. $this->contextNode->setAttribute('phpunit', $phpUnitVersion);
  32706. $this->contextNode->setAttribute('coverage', $coverageVersion);
  32707. }
  32708. private function nodeByName(string $name): DOMElement
  32709. {
  32710. $node = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', $name)->item(0);
  32711. if (!$node) {
  32712. $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', $name));
  32713. }
  32714. return $node;
  32715. }
  32716. }
  32717. <?php
  32718. declare (strict_types=1);
  32719. /*
  32720. * This file is part of phpunit/php-code-coverage.
  32721. *
  32722. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32723. *
  32724. * For the full copyright and license information, please view the LICENSE
  32725. * file that was distributed with this source code.
  32726. */
  32727. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  32728. use DOMElement;
  32729. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ReportAlreadyFinalizedException;
  32730. use XMLWriter;
  32731. /**
  32732. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  32733. */
  32734. final class Coverage
  32735. {
  32736. private readonly XMLWriter $writer;
  32737. private readonly DOMElement $contextNode;
  32738. private bool $finalized = \false;
  32739. public function __construct(DOMElement $context, string $line)
  32740. {
  32741. $this->contextNode = $context;
  32742. $this->writer = new XMLWriter();
  32743. $this->writer->openMemory();
  32744. $this->writer->startElementNS(null, $context->nodeName, 'https://schema.phpunit.de/coverage/1.0');
  32745. $this->writer->writeAttribute('nr', $line);
  32746. }
  32747. /**
  32748. * @throws ReportAlreadyFinalizedException
  32749. */
  32750. public function addTest(string $test): void
  32751. {
  32752. if ($this->finalized) {
  32753. throw new ReportAlreadyFinalizedException();
  32754. }
  32755. $this->writer->startElement('covered');
  32756. $this->writer->writeAttribute('by', $test);
  32757. $this->writer->endElement();
  32758. }
  32759. public function finalize(): void
  32760. {
  32761. $this->writer->endElement();
  32762. $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
  32763. $fragment->appendXML($this->writer->outputMemory());
  32764. $this->contextNode->parentNode->replaceChild($fragment, $this->contextNode);
  32765. $this->finalized = \true;
  32766. }
  32767. }
  32768. <?php
  32769. declare (strict_types=1);
  32770. /*
  32771. * This file is part of phpunit/php-code-coverage.
  32772. *
  32773. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32774. *
  32775. * For the full copyright and license information, please view the LICENSE
  32776. * file that was distributed with this source code.
  32777. */
  32778. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  32779. /**
  32780. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  32781. */
  32782. final class Directory extends Node
  32783. {
  32784. }
  32785. <?php
  32786. declare (strict_types=1);
  32787. /*
  32788. * This file is part of phpunit/php-code-coverage.
  32789. *
  32790. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32791. *
  32792. * For the full copyright and license information, please view the LICENSE
  32793. * file that was distributed with this source code.
  32794. */
  32795. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  32796. use const DIRECTORY_SEPARATOR;
  32797. use const PHP_EOL;
  32798. use function count;
  32799. use function dirname;
  32800. use function file_get_contents;
  32801. use function file_put_contents;
  32802. use function is_array;
  32803. use function is_dir;
  32804. use function is_file;
  32805. use function is_writable;
  32806. use function libxml_clear_errors;
  32807. use function libxml_get_errors;
  32808. use function libxml_use_internal_errors;
  32809. use function sprintf;
  32810. use function strlen;
  32811. use function substr;
  32812. use DateTimeImmutable;
  32813. use DOMDocument;
  32814. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  32815. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\PathExistsButIsNotDirectoryException;
  32816. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
  32817. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
  32818. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
  32819. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
  32820. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem as DirectoryUtil;
  32821. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Version;
  32822. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\XmlException;
  32823. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  32824. final class Facade
  32825. {
  32826. private string $target;
  32827. private Project $project;
  32828. private readonly string $phpUnitVersion;
  32829. public function __construct(string $version)
  32830. {
  32831. $this->phpUnitVersion = $version;
  32832. }
  32833. /**
  32834. * @throws XmlException
  32835. */
  32836. public function process(CodeCoverage $coverage, string $target): void
  32837. {
  32838. if (substr($target, -1, 1) !== DIRECTORY_SEPARATOR) {
  32839. $target .= DIRECTORY_SEPARATOR;
  32840. }
  32841. $this->target = $target;
  32842. $this->initTargetDirectory($target);
  32843. $report = $coverage->getReport();
  32844. $this->project = new Project($coverage->getReport()->name());
  32845. $this->setBuildInformation();
  32846. $this->processTests($coverage->getTests());
  32847. $this->processDirectory($report, $this->project);
  32848. $this->saveDocument($this->project->asDom(), 'index');
  32849. }
  32850. private function setBuildInformation(): void
  32851. {
  32852. $buildNode = $this->project->buildInformation();
  32853. $buildNode->setRuntimeInformation(new Runtime());
  32854. $buildNode->setBuildTime(new DateTimeImmutable());
  32855. $buildNode->setGeneratorVersions($this->phpUnitVersion, Version::id());
  32856. }
  32857. /**
  32858. * @throws PathExistsButIsNotDirectoryException
  32859. * @throws WriteOperationFailedException
  32860. */
  32861. private function initTargetDirectory(string $directory): void
  32862. {
  32863. if (is_file($directory)) {
  32864. if (!is_dir($directory)) {
  32865. throw new PathExistsButIsNotDirectoryException($directory);
  32866. }
  32867. if (!is_writable($directory)) {
  32868. throw new WriteOperationFailedException($directory);
  32869. }
  32870. }
  32871. DirectoryUtil::createDirectory($directory);
  32872. }
  32873. /**
  32874. * @throws XmlException
  32875. */
  32876. private function processDirectory(DirectoryNode $directory, Node $context): void
  32877. {
  32878. $directoryName = $directory->name();
  32879. if ($this->project->projectSourceDirectory() === $directoryName) {
  32880. $directoryName = '/';
  32881. }
  32882. $directoryObject = $context->addDirectory($directoryName);
  32883. $this->setTotals($directory, $directoryObject->totals());
  32884. foreach ($directory->directories() as $node) {
  32885. $this->processDirectory($node, $directoryObject);
  32886. }
  32887. foreach ($directory->files() as $node) {
  32888. $this->processFile($node, $directoryObject);
  32889. }
  32890. }
  32891. /**
  32892. * @throws XmlException
  32893. */
  32894. private function processFile(FileNode $file, Directory $context): void
  32895. {
  32896. $fileObject = $context->addFile($file->name(), $file->id() . '.xml');
  32897. $this->setTotals($file, $fileObject->totals());
  32898. $path = substr($file->pathAsString(), strlen($this->project->projectSourceDirectory()));
  32899. $fileReport = new Report($path);
  32900. $this->setTotals($file, $fileReport->totals());
  32901. foreach ($file->classesAndTraits() as $unit) {
  32902. $this->processUnit($unit, $fileReport);
  32903. }
  32904. foreach ($file->functions() as $function) {
  32905. $this->processFunction($function, $fileReport);
  32906. }
  32907. foreach ($file->lineCoverageData() as $line => $tests) {
  32908. if (!is_array($tests) || count($tests) === 0) {
  32909. continue;
  32910. }
  32911. $coverage = $fileReport->lineCoverage((string) $line);
  32912. foreach ($tests as $test) {
  32913. $coverage->addTest($test);
  32914. }
  32915. $coverage->finalize();
  32916. }
  32917. $fileReport->source()->setSourceCode(file_get_contents($file->pathAsString()));
  32918. $this->saveDocument($fileReport->asDom(), $file->id());
  32919. }
  32920. private function processUnit(array $unit, Report $report): void
  32921. {
  32922. if (isset($unit['className'])) {
  32923. $unitObject = $report->classObject($unit['className']);
  32924. } else {
  32925. $unitObject = $report->traitObject($unit['traitName']);
  32926. }
  32927. $unitObject->setLines($unit['startLine'], $unit['executableLines'], $unit['executedLines']);
  32928. $unitObject->setCrap((float) $unit['crap']);
  32929. $unitObject->setNamespace($unit['namespace']);
  32930. foreach ($unit['methods'] as $method) {
  32931. $methodObject = $unitObject->addMethod($method['methodName']);
  32932. $methodObject->setSignature($method['signature']);
  32933. $methodObject->setLines((string) $method['startLine'], (string) $method['endLine']);
  32934. $methodObject->setCrap($method['crap']);
  32935. $methodObject->setTotals((string) $method['executableLines'], (string) $method['executedLines'], (string) $method['coverage']);
  32936. }
  32937. }
  32938. private function processFunction(array $function, Report $report): void
  32939. {
  32940. $functionObject = $report->functionObject($function['functionName']);
  32941. $functionObject->setSignature($function['signature']);
  32942. $functionObject->setLines((string) $function['startLine']);
  32943. $functionObject->setCrap($function['crap']);
  32944. $functionObject->setTotals((string) $function['executableLines'], (string) $function['executedLines'], (string) $function['coverage']);
  32945. }
  32946. private function processTests(array $tests): void
  32947. {
  32948. $testsObject = $this->project->tests();
  32949. foreach ($tests as $test => $result) {
  32950. $testsObject->addTest($test, $result);
  32951. }
  32952. }
  32953. private function setTotals(AbstractNode $node, Totals $totals): void
  32954. {
  32955. $loc = $node->linesOfCode();
  32956. $totals->setNumLines($loc['linesOfCode'], $loc['commentLinesOfCode'], $loc['nonCommentLinesOfCode'], $node->numberOfExecutableLines(), $node->numberOfExecutedLines());
  32957. $totals->setNumClasses($node->numberOfClasses(), $node->numberOfTestedClasses());
  32958. $totals->setNumTraits($node->numberOfTraits(), $node->numberOfTestedTraits());
  32959. $totals->setNumMethods($node->numberOfMethods(), $node->numberOfTestedMethods());
  32960. $totals->setNumFunctions($node->numberOfFunctions(), $node->numberOfTestedFunctions());
  32961. }
  32962. private function targetDirectory(): string
  32963. {
  32964. return $this->target;
  32965. }
  32966. /**
  32967. * @throws XmlException
  32968. */
  32969. private function saveDocument(DOMDocument $document, string $name): void
  32970. {
  32971. $filename = sprintf('%s/%s.xml', $this->targetDirectory(), $name);
  32972. $document->formatOutput = \true;
  32973. $document->preserveWhiteSpace = \false;
  32974. $this->initTargetDirectory(dirname($filename));
  32975. file_put_contents($filename, $this->documentAsString($document));
  32976. }
  32977. /**
  32978. * @throws XmlException
  32979. *
  32980. * @see https://bugs.php.net/bug.php?id=79191
  32981. */
  32982. private function documentAsString(DOMDocument $document): string
  32983. {
  32984. $xmlErrorHandling = libxml_use_internal_errors(\true);
  32985. $xml = $document->saveXML();
  32986. if ($xml === \false) {
  32987. $message = 'Unable to generate the XML';
  32988. foreach (libxml_get_errors() as $error) {
  32989. $message .= PHP_EOL . $error->message;
  32990. }
  32991. throw new XmlException($message);
  32992. }
  32993. libxml_clear_errors();
  32994. libxml_use_internal_errors($xmlErrorHandling);
  32995. return $xml;
  32996. }
  32997. }
  32998. <?php
  32999. declare (strict_types=1);
  33000. /*
  33001. * This file is part of phpunit/php-code-coverage.
  33002. *
  33003. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33004. *
  33005. * For the full copyright and license information, please view the LICENSE
  33006. * file that was distributed with this source code.
  33007. */
  33008. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33009. use DOMDocument;
  33010. use DOMElement;
  33011. /**
  33012. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33013. */
  33014. class File
  33015. {
  33016. private readonly DOMDocument $dom;
  33017. private readonly DOMElement $contextNode;
  33018. public function __construct(DOMElement $context)
  33019. {
  33020. $this->dom = $context->ownerDocument;
  33021. $this->contextNode = $context;
  33022. }
  33023. public function totals(): Totals
  33024. {
  33025. $totalsContainer = $this->contextNode->firstChild;
  33026. if (!$totalsContainer) {
  33027. $totalsContainer = $this->contextNode->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'totals'));
  33028. }
  33029. return new Totals($totalsContainer);
  33030. }
  33031. public function lineCoverage(string $line): Coverage
  33032. {
  33033. $coverage = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'coverage')->item(0);
  33034. if (!$coverage) {
  33035. $coverage = $this->contextNode->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'coverage'));
  33036. }
  33037. $lineNode = $coverage->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'line'));
  33038. return new Coverage($lineNode, $line);
  33039. }
  33040. protected function contextNode(): DOMElement
  33041. {
  33042. return $this->contextNode;
  33043. }
  33044. protected function dom(): DOMDocument
  33045. {
  33046. return $this->dom;
  33047. }
  33048. }
  33049. <?php
  33050. declare (strict_types=1);
  33051. /*
  33052. * This file is part of phpunit/php-code-coverage.
  33053. *
  33054. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33055. *
  33056. * For the full copyright and license information, please view the LICENSE
  33057. * file that was distributed with this source code.
  33058. */
  33059. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33060. use DOMElement;
  33061. /**
  33062. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33063. */
  33064. final class Method
  33065. {
  33066. private readonly DOMElement $contextNode;
  33067. public function __construct(DOMElement $context, string $name)
  33068. {
  33069. $this->contextNode = $context;
  33070. $this->setName($name);
  33071. }
  33072. public function setSignature(string $signature): void
  33073. {
  33074. $this->contextNode->setAttribute('signature', $signature);
  33075. }
  33076. public function setLines(string $start, ?string $end = null): void
  33077. {
  33078. $this->contextNode->setAttribute('start', $start);
  33079. if ($end !== null) {
  33080. $this->contextNode->setAttribute('end', $end);
  33081. }
  33082. }
  33083. public function setTotals(string $executable, string $executed, string $coverage): void
  33084. {
  33085. $this->contextNode->setAttribute('executable', $executable);
  33086. $this->contextNode->setAttribute('executed', $executed);
  33087. $this->contextNode->setAttribute('coverage', $coverage);
  33088. }
  33089. public function setCrap(string $crap): void
  33090. {
  33091. $this->contextNode->setAttribute('crap', $crap);
  33092. }
  33093. private function setName(string $name): void
  33094. {
  33095. $this->contextNode->setAttribute('name', $name);
  33096. }
  33097. }
  33098. <?php
  33099. declare (strict_types=1);
  33100. /*
  33101. * This file is part of phpunit/php-code-coverage.
  33102. *
  33103. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33104. *
  33105. * For the full copyright and license information, please view the LICENSE
  33106. * file that was distributed with this source code.
  33107. */
  33108. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33109. use DOMDocument;
  33110. use DOMElement;
  33111. /**
  33112. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33113. */
  33114. abstract class Node
  33115. {
  33116. private DOMDocument $dom;
  33117. private DOMElement $contextNode;
  33118. public function __construct(DOMElement $context)
  33119. {
  33120. $this->setContextNode($context);
  33121. }
  33122. public function dom(): DOMDocument
  33123. {
  33124. return $this->dom;
  33125. }
  33126. public function totals(): Totals
  33127. {
  33128. $totalsContainer = $this->contextNode()->firstChild;
  33129. if (!$totalsContainer) {
  33130. $totalsContainer = $this->contextNode()->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'totals'));
  33131. }
  33132. return new Totals($totalsContainer);
  33133. }
  33134. public function addDirectory(string $name): Directory
  33135. {
  33136. $dirNode = $this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'directory');
  33137. $dirNode->setAttribute('name', $name);
  33138. $this->contextNode()->appendChild($dirNode);
  33139. return new Directory($dirNode);
  33140. }
  33141. public function addFile(string $name, string $href): File
  33142. {
  33143. $fileNode = $this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'file');
  33144. $fileNode->setAttribute('name', $name);
  33145. $fileNode->setAttribute('href', $href);
  33146. $this->contextNode()->appendChild($fileNode);
  33147. return new File($fileNode);
  33148. }
  33149. protected function setContextNode(DOMElement $context): void
  33150. {
  33151. $this->dom = $context->ownerDocument;
  33152. $this->contextNode = $context;
  33153. }
  33154. protected function contextNode(): DOMElement
  33155. {
  33156. return $this->contextNode;
  33157. }
  33158. }
  33159. <?php
  33160. declare (strict_types=1);
  33161. /*
  33162. * This file is part of phpunit/php-code-coverage.
  33163. *
  33164. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33165. *
  33166. * For the full copyright and license information, please view the LICENSE
  33167. * file that was distributed with this source code.
  33168. */
  33169. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33170. use DOMDocument;
  33171. /**
  33172. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33173. */
  33174. final class Project extends Node
  33175. {
  33176. public function __construct(string $directory)
  33177. {
  33178. $this->init();
  33179. $this->setProjectSourceDirectory($directory);
  33180. }
  33181. public function projectSourceDirectory(): string
  33182. {
  33183. return $this->contextNode()->getAttribute('source');
  33184. }
  33185. public function buildInformation(): BuildInformation
  33186. {
  33187. $buildNode = $this->dom()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'build')->item(0);
  33188. if (!$buildNode) {
  33189. $buildNode = $this->dom()->documentElement->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'build'));
  33190. }
  33191. return new BuildInformation($buildNode);
  33192. }
  33193. public function tests(): Tests
  33194. {
  33195. $testsNode = $this->contextNode()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'tests')->item(0);
  33196. if (!$testsNode) {
  33197. $testsNode = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'tests'));
  33198. }
  33199. return new Tests($testsNode);
  33200. }
  33201. public function asDom(): DOMDocument
  33202. {
  33203. return $this->dom();
  33204. }
  33205. private function init(): void
  33206. {
  33207. $dom = new DOMDocument();
  33208. $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
  33209. $this->setContextNode($dom->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'project')->item(0));
  33210. }
  33211. private function setProjectSourceDirectory(string $name): void
  33212. {
  33213. $this->contextNode()->setAttribute('source', $name);
  33214. }
  33215. }
  33216. <?php
  33217. declare (strict_types=1);
  33218. /*
  33219. * This file is part of phpunit/php-code-coverage.
  33220. *
  33221. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33222. *
  33223. * For the full copyright and license information, please view the LICENSE
  33224. * file that was distributed with this source code.
  33225. */
  33226. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33227. use function basename;
  33228. use function dirname;
  33229. use DOMDocument;
  33230. /**
  33231. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33232. */
  33233. final class Report extends File
  33234. {
  33235. public function __construct(string $name)
  33236. {
  33237. $dom = new DOMDocument();
  33238. $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
  33239. $contextNode = $dom->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'file')->item(0);
  33240. parent::__construct($contextNode);
  33241. $this->setName($name);
  33242. }
  33243. public function asDom(): DOMDocument
  33244. {
  33245. return $this->dom();
  33246. }
  33247. public function functionObject($name): Method
  33248. {
  33249. $node = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'function'));
  33250. return new Method($node, $name);
  33251. }
  33252. public function classObject($name): Unit
  33253. {
  33254. return $this->unitObject('class', $name);
  33255. }
  33256. public function traitObject($name): Unit
  33257. {
  33258. return $this->unitObject('trait', $name);
  33259. }
  33260. public function source(): Source
  33261. {
  33262. $source = $this->contextNode()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'source')->item(0);
  33263. if (!$source) {
  33264. $source = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'source'));
  33265. }
  33266. return new Source($source);
  33267. }
  33268. private function setName(string $name): void
  33269. {
  33270. $this->contextNode()->setAttribute('name', basename($name));
  33271. $this->contextNode()->setAttribute('path', dirname($name));
  33272. }
  33273. private function unitObject(string $tagName, $name): Unit
  33274. {
  33275. $node = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', $tagName));
  33276. return new Unit($node, $name);
  33277. }
  33278. }
  33279. <?php
  33280. declare (strict_types=1);
  33281. /*
  33282. * This file is part of phpunit/php-code-coverage.
  33283. *
  33284. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33285. *
  33286. * For the full copyright and license information, please view the LICENSE
  33287. * file that was distributed with this source code.
  33288. */
  33289. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33290. use DOMElement;
  33291. use PHPUnitPHAR\TheSeer\Tokenizer\NamespaceUri;
  33292. use PHPUnitPHAR\TheSeer\Tokenizer\Tokenizer;
  33293. use PHPUnitPHAR\TheSeer\Tokenizer\XMLSerializer;
  33294. /**
  33295. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33296. */
  33297. final class Source
  33298. {
  33299. private readonly DOMElement $context;
  33300. public function __construct(DOMElement $context)
  33301. {
  33302. $this->context = $context;
  33303. }
  33304. public function setSourceCode(string $source): void
  33305. {
  33306. $context = $this->context;
  33307. $tokens = (new Tokenizer())->parse($source);
  33308. $srcDom = (new XMLSerializer(new NamespaceUri($context->namespaceURI)))->toDom($tokens);
  33309. $context->parentNode->replaceChild($context->ownerDocument->importNode($srcDom->documentElement, \true), $context);
  33310. }
  33311. }
  33312. <?php
  33313. declare (strict_types=1);
  33314. /*
  33315. * This file is part of phpunit/php-code-coverage.
  33316. *
  33317. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33318. *
  33319. * For the full copyright and license information, please view the LICENSE
  33320. * file that was distributed with this source code.
  33321. */
  33322. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33323. use DOMElement;
  33324. /**
  33325. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33326. *
  33327. * @psalm-import-type TestType from \SebastianBergmann\CodeCoverage\CodeCoverage
  33328. */
  33329. final class Tests
  33330. {
  33331. private readonly DOMElement $contextNode;
  33332. public function __construct(DOMElement $context)
  33333. {
  33334. $this->contextNode = $context;
  33335. }
  33336. /**
  33337. * @param TestType $result
  33338. */
  33339. public function addTest(string $test, array $result): void
  33340. {
  33341. $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'test'));
  33342. $node->setAttribute('name', $test);
  33343. $node->setAttribute('size', $result['size']);
  33344. $node->setAttribute('status', $result['status']);
  33345. }
  33346. }
  33347. <?php
  33348. declare (strict_types=1);
  33349. /*
  33350. * This file is part of phpunit/php-code-coverage.
  33351. *
  33352. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33353. *
  33354. * For the full copyright and license information, please view the LICENSE
  33355. * file that was distributed with this source code.
  33356. */
  33357. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33358. use function sprintf;
  33359. use DOMElement;
  33360. use DOMNode;
  33361. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
  33362. /**
  33363. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33364. */
  33365. final class Totals
  33366. {
  33367. private readonly DOMNode $container;
  33368. private readonly DOMElement $linesNode;
  33369. private readonly DOMElement $methodsNode;
  33370. private readonly DOMElement $functionsNode;
  33371. private readonly DOMElement $classesNode;
  33372. private readonly DOMElement $traitsNode;
  33373. public function __construct(DOMElement $container)
  33374. {
  33375. $this->container = $container;
  33376. $dom = $container->ownerDocument;
  33377. $this->linesNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'lines');
  33378. $this->methodsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'methods');
  33379. $this->functionsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'functions');
  33380. $this->classesNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'classes');
  33381. $this->traitsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'traits');
  33382. $container->appendChild($this->linesNode);
  33383. $container->appendChild($this->methodsNode);
  33384. $container->appendChild($this->functionsNode);
  33385. $container->appendChild($this->classesNode);
  33386. $container->appendChild($this->traitsNode);
  33387. }
  33388. public function container(): DOMNode
  33389. {
  33390. return $this->container;
  33391. }
  33392. public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
  33393. {
  33394. $this->linesNode->setAttribute('total', (string) $loc);
  33395. $this->linesNode->setAttribute('comments', (string) $cloc);
  33396. $this->linesNode->setAttribute('code', (string) $ncloc);
  33397. $this->linesNode->setAttribute('executable', (string) $executable);
  33398. $this->linesNode->setAttribute('executed', (string) $executed);
  33399. $this->linesNode->setAttribute('percent', $executable === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($executed, $executable)->asFloat()));
  33400. }
  33401. public function setNumClasses(int $count, int $tested): void
  33402. {
  33403. $this->classesNode->setAttribute('count', (string) $count);
  33404. $this->classesNode->setAttribute('tested', (string) $tested);
  33405. $this->classesNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
  33406. }
  33407. public function setNumTraits(int $count, int $tested): void
  33408. {
  33409. $this->traitsNode->setAttribute('count', (string) $count);
  33410. $this->traitsNode->setAttribute('tested', (string) $tested);
  33411. $this->traitsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
  33412. }
  33413. public function setNumMethods(int $count, int $tested): void
  33414. {
  33415. $this->methodsNode->setAttribute('count', (string) $count);
  33416. $this->methodsNode->setAttribute('tested', (string) $tested);
  33417. $this->methodsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
  33418. }
  33419. public function setNumFunctions(int $count, int $tested): void
  33420. {
  33421. $this->functionsNode->setAttribute('count', (string) $count);
  33422. $this->functionsNode->setAttribute('tested', (string) $tested);
  33423. $this->functionsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
  33424. }
  33425. }
  33426. <?php
  33427. declare (strict_types=1);
  33428. /*
  33429. * This file is part of phpunit/php-code-coverage.
  33430. *
  33431. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33432. *
  33433. * For the full copyright and license information, please view the LICENSE
  33434. * file that was distributed with this source code.
  33435. */
  33436. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
  33437. use DOMElement;
  33438. /**
  33439. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33440. */
  33441. final class Unit
  33442. {
  33443. private readonly DOMElement $contextNode;
  33444. public function __construct(DOMElement $context, string $name)
  33445. {
  33446. $this->contextNode = $context;
  33447. $this->setName($name);
  33448. }
  33449. public function setLines(int $start, int $executable, int $executed): void
  33450. {
  33451. $this->contextNode->setAttribute('start', (string) $start);
  33452. $this->contextNode->setAttribute('executable', (string) $executable);
  33453. $this->contextNode->setAttribute('executed', (string) $executed);
  33454. }
  33455. public function setCrap(float $crap): void
  33456. {
  33457. $this->contextNode->setAttribute('crap', (string) $crap);
  33458. }
  33459. public function setNamespace(string $namespace): void
  33460. {
  33461. $node = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'namespace')->item(0);
  33462. if (!$node) {
  33463. $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'namespace'));
  33464. }
  33465. $node->setAttribute('name', $namespace);
  33466. }
  33467. public function addMethod(string $name): Method
  33468. {
  33469. $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'method'));
  33470. return new Method($node, $name);
  33471. }
  33472. private function setName(string $name): void
  33473. {
  33474. $this->contextNode->setAttribute('name', $name);
  33475. }
  33476. }
  33477. <?php
  33478. declare (strict_types=1);
  33479. /*
  33480. * This file is part of phpunit/php-code-coverage.
  33481. *
  33482. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33483. *
  33484. * For the full copyright and license information, please view the LICENSE
  33485. * file that was distributed with this source code.
  33486. */
  33487. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  33488. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  33489. final class CacheWarmer
  33490. {
  33491. public function warmCache(string $cacheDirectory, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode, Filter $filter): void
  33492. {
  33493. $analyser = new CachingFileAnalyser($cacheDirectory, new ParsingFileAnalyser($useAnnotationsForIgnoringCode, $ignoreDeprecatedCode), $useAnnotationsForIgnoringCode, $ignoreDeprecatedCode);
  33494. foreach ($filter->files() as $file) {
  33495. $analyser->process($file);
  33496. }
  33497. }
  33498. }
  33499. <?php
  33500. declare (strict_types=1);
  33501. /*
  33502. * This file is part of phpunit/php-code-coverage.
  33503. *
  33504. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33505. *
  33506. * For the full copyright and license information, please view the LICENSE
  33507. * file that was distributed with this source code.
  33508. */
  33509. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  33510. use function file_get_contents;
  33511. use function file_put_contents;
  33512. use function implode;
  33513. use function is_file;
  33514. use function md5;
  33515. use function serialize;
  33516. use function unserialize;
  33517. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
  33518. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  33519. /**
  33520. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33521. *
  33522. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  33523. */
  33524. final class CachingFileAnalyser implements FileAnalyser
  33525. {
  33526. private static ?string $cacheVersion = null;
  33527. private readonly string $directory;
  33528. private readonly FileAnalyser $analyser;
  33529. private readonly bool $useAnnotationsForIgnoringCode;
  33530. private readonly bool $ignoreDeprecatedCode;
  33531. private array $cache = [];
  33532. public function __construct(string $directory, FileAnalyser $analyser, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode)
  33533. {
  33534. Filesystem::createDirectory($directory);
  33535. $this->analyser = $analyser;
  33536. $this->directory = $directory;
  33537. $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
  33538. $this->ignoreDeprecatedCode = $ignoreDeprecatedCode;
  33539. }
  33540. public function classesIn(string $filename): array
  33541. {
  33542. if (!isset($this->cache[$filename])) {
  33543. $this->process($filename);
  33544. }
  33545. return $this->cache[$filename]['classesIn'];
  33546. }
  33547. public function traitsIn(string $filename): array
  33548. {
  33549. if (!isset($this->cache[$filename])) {
  33550. $this->process($filename);
  33551. }
  33552. return $this->cache[$filename]['traitsIn'];
  33553. }
  33554. public function functionsIn(string $filename): array
  33555. {
  33556. if (!isset($this->cache[$filename])) {
  33557. $this->process($filename);
  33558. }
  33559. return $this->cache[$filename]['functionsIn'];
  33560. }
  33561. /**
  33562. * @psalm-return LinesOfCodeType
  33563. */
  33564. public function linesOfCodeFor(string $filename): array
  33565. {
  33566. if (!isset($this->cache[$filename])) {
  33567. $this->process($filename);
  33568. }
  33569. return $this->cache[$filename]['linesOfCodeFor'];
  33570. }
  33571. public function executableLinesIn(string $filename): array
  33572. {
  33573. if (!isset($this->cache[$filename])) {
  33574. $this->process($filename);
  33575. }
  33576. return $this->cache[$filename]['executableLinesIn'];
  33577. }
  33578. public function ignoredLinesFor(string $filename): array
  33579. {
  33580. if (!isset($this->cache[$filename])) {
  33581. $this->process($filename);
  33582. }
  33583. return $this->cache[$filename]['ignoredLinesFor'];
  33584. }
  33585. public function process(string $filename): void
  33586. {
  33587. $cache = $this->read($filename);
  33588. if ($cache !== \false) {
  33589. $this->cache[$filename] = $cache;
  33590. return;
  33591. }
  33592. $this->cache[$filename] = ['classesIn' => $this->analyser->classesIn($filename), 'traitsIn' => $this->analyser->traitsIn($filename), 'functionsIn' => $this->analyser->functionsIn($filename), 'linesOfCodeFor' => $this->analyser->linesOfCodeFor($filename), 'ignoredLinesFor' => $this->analyser->ignoredLinesFor($filename), 'executableLinesIn' => $this->analyser->executableLinesIn($filename)];
  33593. $this->write($filename, $this->cache[$filename]);
  33594. }
  33595. private function read(string $filename): array|false
  33596. {
  33597. $cacheFile = $this->cacheFile($filename);
  33598. if (!is_file($cacheFile)) {
  33599. return \false;
  33600. }
  33601. return unserialize(file_get_contents($cacheFile), ['allowed_classes' => \false]);
  33602. }
  33603. private function write(string $filename, array $data): void
  33604. {
  33605. file_put_contents($this->cacheFile($filename), serialize($data));
  33606. }
  33607. private function cacheFile(string $filename): string
  33608. {
  33609. $cacheKey = md5(implode("\x00", [$filename, file_get_contents($filename), self::cacheVersion(), $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode]));
  33610. return $this->directory . \DIRECTORY_SEPARATOR . $cacheKey;
  33611. }
  33612. private static function cacheVersion(): string
  33613. {
  33614. if (self::$cacheVersion !== null) {
  33615. return self::$cacheVersion;
  33616. }
  33617. $buffer = [];
  33618. foreach ((new FileIteratorFacade())->getFilesAsArray(__DIR__, '.php') as $file) {
  33619. $buffer[] = $file;
  33620. $buffer[] = file_get_contents($file);
  33621. }
  33622. self::$cacheVersion = md5(implode("\x00", $buffer));
  33623. return self::$cacheVersion;
  33624. }
  33625. }
  33626. <?php
  33627. declare (strict_types=1);
  33628. /*
  33629. * This file is part of phpunit/php-code-coverage.
  33630. *
  33631. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33632. *
  33633. * For the full copyright and license information, please view the LICENSE
  33634. * file that was distributed with this source code.
  33635. */
  33636. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  33637. use function assert;
  33638. use function implode;
  33639. use function rtrim;
  33640. use function trim;
  33641. use PHPUnitPHAR\PhpParser\Node;
  33642. use PHPUnitPHAR\PhpParser\Node\ComplexType;
  33643. use PHPUnitPHAR\PhpParser\Node\Identifier;
  33644. use PHPUnitPHAR\PhpParser\Node\IntersectionType;
  33645. use PHPUnitPHAR\PhpParser\Node\Name;
  33646. use PHPUnitPHAR\PhpParser\Node\NullableType;
  33647. use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
  33648. use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
  33649. use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
  33650. use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
  33651. use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
  33652. use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
  33653. use PHPUnitPHAR\PhpParser\Node\UnionType;
  33654. use PHPUnitPHAR\PhpParser\NodeTraverser;
  33655. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  33656. use PHPUnitPHAR\SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor;
  33657. /**
  33658. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33659. *
  33660. * @psalm-type CodeUnitFunctionType = array{
  33661. * name: string,
  33662. * namespacedName: string,
  33663. * namespace: string,
  33664. * signature: string,
  33665. * startLine: int,
  33666. * endLine: int,
  33667. * ccn: int
  33668. * }
  33669. * @psalm-type CodeUnitMethodType = array{
  33670. * methodName: string,
  33671. * signature: string,
  33672. * visibility: string,
  33673. * startLine: int,
  33674. * endLine: int,
  33675. * ccn: int
  33676. * }
  33677. * @psalm-type CodeUnitClassType = array{
  33678. * name: string,
  33679. * namespacedName: string,
  33680. * namespace: string,
  33681. * startLine: int,
  33682. * endLine: int,
  33683. * methods: array<string, CodeUnitMethodType>
  33684. * }
  33685. * @psalm-type CodeUnitTraitType = array{
  33686. * name: string,
  33687. * namespacedName: string,
  33688. * namespace: string,
  33689. * startLine: int,
  33690. * endLine: int,
  33691. * methods: array<string, CodeUnitMethodType>
  33692. * }
  33693. */
  33694. final class CodeUnitFindingVisitor extends NodeVisitorAbstract
  33695. {
  33696. /**
  33697. * @psalm-var array<string, CodeUnitClassType>
  33698. */
  33699. private array $classes = [];
  33700. /**
  33701. * @psalm-var array<string, CodeUnitTraitType>
  33702. */
  33703. private array $traits = [];
  33704. /**
  33705. * @psalm-var array<string, CodeUnitFunctionType>
  33706. */
  33707. private array $functions = [];
  33708. public function enterNode(Node $node): void
  33709. {
  33710. if ($node instanceof Class_) {
  33711. if ($node->isAnonymous()) {
  33712. return;
  33713. }
  33714. $this->processClass($node);
  33715. }
  33716. if ($node instanceof Trait_) {
  33717. $this->processTrait($node);
  33718. }
  33719. if (!$node instanceof ClassMethod && !$node instanceof Function_) {
  33720. return;
  33721. }
  33722. if ($node instanceof ClassMethod) {
  33723. $parentNode = $node->getAttribute('parent');
  33724. if ($parentNode instanceof Class_ && $parentNode->isAnonymous()) {
  33725. return;
  33726. }
  33727. $this->processMethod($node);
  33728. return;
  33729. }
  33730. $this->processFunction($node);
  33731. }
  33732. /**
  33733. * @psalm-return array<string, CodeUnitClassType>
  33734. */
  33735. public function classes(): array
  33736. {
  33737. return $this->classes;
  33738. }
  33739. /**
  33740. * @psalm-return array<string, CodeUnitTraitType>
  33741. */
  33742. public function traits(): array
  33743. {
  33744. return $this->traits;
  33745. }
  33746. /**
  33747. * @psalm-return array<string, CodeUnitFunctionType>
  33748. */
  33749. public function functions(): array
  33750. {
  33751. return $this->functions;
  33752. }
  33753. private function cyclomaticComplexity(ClassMethod|Function_ $node): int
  33754. {
  33755. $nodes = $node->getStmts();
  33756. if ($nodes === null) {
  33757. return 0;
  33758. }
  33759. $traverser = new NodeTraverser();
  33760. $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor();
  33761. $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
  33762. /* @noinspection UnusedFunctionResultInspection */
  33763. $traverser->traverse($nodes);
  33764. return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
  33765. }
  33766. private function signature(ClassMethod|Function_ $node): string
  33767. {
  33768. $signature = ($node->returnsByRef() ? '&' : '') . $node->name->toString() . '(';
  33769. $parameters = [];
  33770. foreach ($node->getParams() as $parameter) {
  33771. assert(isset($parameter->var->name));
  33772. $parameterAsString = '';
  33773. if ($parameter->type !== null) {
  33774. $parameterAsString = $this->type($parameter->type) . ' ';
  33775. }
  33776. $parameterAsString .= '$' . $parameter->var->name;
  33777. /* @todo Handle default values */
  33778. $parameters[] = $parameterAsString;
  33779. }
  33780. $signature .= implode(', ', $parameters) . ')';
  33781. $returnType = $node->getReturnType();
  33782. if ($returnType !== null) {
  33783. $signature .= ': ' . $this->type($returnType);
  33784. }
  33785. return $signature;
  33786. }
  33787. private function type(ComplexType|Identifier|Name $type): string
  33788. {
  33789. if ($type instanceof NullableType) {
  33790. return '?' . $type->type;
  33791. }
  33792. if ($type instanceof UnionType) {
  33793. return $this->unionTypeAsString($type);
  33794. }
  33795. if ($type instanceof IntersectionType) {
  33796. return $this->intersectionTypeAsString($type);
  33797. }
  33798. return $type->toString();
  33799. }
  33800. private function visibility(ClassMethod $node): string
  33801. {
  33802. if ($node->isPrivate()) {
  33803. return 'private';
  33804. }
  33805. if ($node->isProtected()) {
  33806. return 'protected';
  33807. }
  33808. return 'public';
  33809. }
  33810. private function processClass(Class_ $node): void
  33811. {
  33812. $name = $node->name->toString();
  33813. $namespacedName = $node->namespacedName->toString();
  33814. $this->classes[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'methods' => []];
  33815. }
  33816. private function processTrait(Trait_ $node): void
  33817. {
  33818. $name = $node->name->toString();
  33819. $namespacedName = $node->namespacedName->toString();
  33820. $this->traits[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'methods' => []];
  33821. }
  33822. private function processMethod(ClassMethod $node): void
  33823. {
  33824. $parentNode = $node->getAttribute('parent');
  33825. if ($parentNode instanceof Interface_) {
  33826. return;
  33827. }
  33828. assert($parentNode instanceof Class_ || $parentNode instanceof Trait_ || $parentNode instanceof Enum_);
  33829. assert(isset($parentNode->name));
  33830. assert(isset($parentNode->namespacedName));
  33831. assert($parentNode->namespacedName instanceof Name);
  33832. $parentName = $parentNode->name->toString();
  33833. $parentNamespacedName = $parentNode->namespacedName->toString();
  33834. if ($parentNode instanceof Class_) {
  33835. $storage =& $this->classes;
  33836. } else {
  33837. $storage =& $this->traits;
  33838. }
  33839. if (!isset($storage[$parentNamespacedName])) {
  33840. $storage[$parentNamespacedName] = ['name' => $parentName, 'namespacedName' => $parentNamespacedName, 'namespace' => $this->namespace($parentNamespacedName, $parentName), 'startLine' => $parentNode->getStartLine(), 'endLine' => $parentNode->getEndLine(), 'methods' => []];
  33841. }
  33842. $storage[$parentNamespacedName]['methods'][$node->name->toString()] = ['methodName' => $node->name->toString(), 'signature' => $this->signature($node), 'visibility' => $this->visibility($node), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'ccn' => $this->cyclomaticComplexity($node)];
  33843. }
  33844. private function processFunction(Function_ $node): void
  33845. {
  33846. assert(isset($node->name));
  33847. assert(isset($node->namespacedName));
  33848. assert($node->namespacedName instanceof Name);
  33849. $name = $node->name->toString();
  33850. $namespacedName = $node->namespacedName->toString();
  33851. $this->functions[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'signature' => $this->signature($node), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'ccn' => $this->cyclomaticComplexity($node)];
  33852. }
  33853. private function namespace(string $namespacedName, string $name): string
  33854. {
  33855. return trim(rtrim($namespacedName, $name), '\\');
  33856. }
  33857. private function unionTypeAsString(UnionType $node): string
  33858. {
  33859. $types = [];
  33860. foreach ($node->types as $type) {
  33861. if ($type instanceof IntersectionType) {
  33862. $types[] = '(' . $this->intersectionTypeAsString($type) . ')';
  33863. continue;
  33864. }
  33865. $types[] = $this->typeAsString($type);
  33866. }
  33867. return implode('|', $types);
  33868. }
  33869. private function intersectionTypeAsString(IntersectionType $node): string
  33870. {
  33871. $types = [];
  33872. foreach ($node->types as $type) {
  33873. $types[] = $this->typeAsString($type);
  33874. }
  33875. return implode('&', $types);
  33876. }
  33877. private function typeAsString(Identifier|Name $node): string
  33878. {
  33879. if ($node instanceof Name) {
  33880. return $node->toCodeString();
  33881. }
  33882. return $node->toString();
  33883. }
  33884. }
  33885. <?php
  33886. declare (strict_types=1);
  33887. /*
  33888. * This file is part of phpunit/php-code-coverage.
  33889. *
  33890. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33891. *
  33892. * For the full copyright and license information, please view the LICENSE
  33893. * file that was distributed with this source code.
  33894. */
  33895. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  33896. use function array_diff_key;
  33897. use function assert;
  33898. use function count;
  33899. use function current;
  33900. use function end;
  33901. use function explode;
  33902. use function max;
  33903. use function preg_match;
  33904. use function preg_quote;
  33905. use function range;
  33906. use function reset;
  33907. use function sprintf;
  33908. use PHPUnitPHAR\PhpParser\Node;
  33909. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  33910. /**
  33911. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  33912. *
  33913. * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  33914. */
  33915. final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract
  33916. {
  33917. private int $nextBranch = 0;
  33918. private readonly string $source;
  33919. /**
  33920. * @psalm-var LinesType
  33921. */
  33922. private array $executableLinesGroupedByBranch = [];
  33923. /**
  33924. * @psalm-var array<int, bool>
  33925. */
  33926. private array $unsets = [];
  33927. /**
  33928. * @psalm-var array<int, string>
  33929. */
  33930. private array $commentsToCheckForUnset = [];
  33931. public function __construct(string $source)
  33932. {
  33933. $this->source = $source;
  33934. }
  33935. public function enterNode(Node $node): void
  33936. {
  33937. foreach ($node->getComments() as $comment) {
  33938. $commentLine = $comment->getStartLine();
  33939. if (!isset($this->executableLinesGroupedByBranch[$commentLine])) {
  33940. continue;
  33941. }
  33942. foreach (explode("\n", $comment->getText()) as $text) {
  33943. $this->commentsToCheckForUnset[$commentLine] = $text;
  33944. $commentLine++;
  33945. }
  33946. }
  33947. if ($node instanceof Node\Scalar\String_ || $node instanceof Node\Scalar\EncapsedStringPart) {
  33948. $startLine = $node->getStartLine() + 1;
  33949. $endLine = $node->getEndLine() - 1;
  33950. if ($startLine <= $endLine) {
  33951. foreach (range($startLine, $endLine) as $line) {
  33952. unset($this->executableLinesGroupedByBranch[$line]);
  33953. }
  33954. }
  33955. return;
  33956. }
  33957. if ($node instanceof Node\Stmt\Interface_) {
  33958. foreach (range($node->getStartLine(), $node->getEndLine()) as $line) {
  33959. $this->unsets[$line] = \true;
  33960. }
  33961. return;
  33962. }
  33963. if ($node instanceof Node\Stmt\Declare_ || $node instanceof Node\Stmt\DeclareDeclare || $node instanceof Node\Stmt\Else_ || $node instanceof Node\Stmt\EnumCase || $node instanceof Node\Stmt\Finally_ || $node instanceof Node\Stmt\GroupUse || $node instanceof Node\Stmt\Label || $node instanceof Node\Stmt\Namespace_ || $node instanceof Node\Stmt\Nop || $node instanceof Node\Stmt\Switch_ || $node instanceof Node\Stmt\TryCatch || $node instanceof Node\Stmt\Use_ || $node instanceof Node\Stmt\UseUse || $node instanceof Node\Expr\ConstFetch || $node instanceof Node\Expr\Variable || $node instanceof Node\Expr\Throw_ || $node instanceof Node\ComplexType || $node instanceof Node\Const_ || $node instanceof Node\Identifier || $node instanceof Node\Name || $node instanceof Node\Param || $node instanceof Node\Scalar) {
  33964. return;
  33965. }
  33966. if ($node instanceof Node\Expr\Match_) {
  33967. foreach ($node->arms as $arm) {
  33968. $this->setLineBranch($arm->body->getStartLine(), $arm->body->getEndLine(), ++$this->nextBranch);
  33969. }
  33970. return;
  33971. }
  33972. /*
  33973. * nikic/php-parser ^4.18 represents <code>throw</code> statements
  33974. * as <code>Stmt\Throw_</code> objects
  33975. */
  33976. if ($node instanceof Node\Stmt\Throw_) {
  33977. $this->setLineBranch($node->expr->getEndLine(), $node->expr->getEndLine(), ++$this->nextBranch);
  33978. return;
  33979. }
  33980. /*
  33981. * nikic/php-parser ^5 represents <code>throw</code> statements
  33982. * as <code>Stmt\Expression</code> objects that contain an
  33983. * <code>Expr\Throw_</code> object
  33984. */
  33985. if ($node instanceof Node\Stmt\Expression && $node->expr instanceof Node\Expr\Throw_) {
  33986. $this->setLineBranch($node->expr->expr->getEndLine(), $node->expr->expr->getEndLine(), ++$this->nextBranch);
  33987. return;
  33988. }
  33989. if ($node instanceof Node\Stmt\Enum_ || $node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure || $node instanceof Node\Stmt\Trait_) {
  33990. if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod) {
  33991. $unsets = [];
  33992. foreach ($node->getParams() as $param) {
  33993. foreach (range($param->getStartLine(), $param->getEndLine()) as $line) {
  33994. $unsets[$line] = \true;
  33995. }
  33996. }
  33997. unset($unsets[$node->getEndLine()]);
  33998. $this->unsets += $unsets;
  33999. }
  34000. $isConcreteClassLike = $node instanceof Node\Stmt\Enum_ || $node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Trait_;
  34001. if (null !== $node->stmts) {
  34002. foreach ($node->stmts as $stmt) {
  34003. if ($stmt instanceof Node\Stmt\Nop) {
  34004. continue;
  34005. }
  34006. foreach (range($stmt->getStartLine(), $stmt->getEndLine()) as $line) {
  34007. unset($this->executableLinesGroupedByBranch[$line]);
  34008. if ($isConcreteClassLike && !$stmt instanceof Node\Stmt\ClassMethod) {
  34009. $this->unsets[$line] = \true;
  34010. }
  34011. }
  34012. }
  34013. }
  34014. if ($isConcreteClassLike) {
  34015. return;
  34016. }
  34017. $hasEmptyBody = [] === $node->stmts || null === $node->stmts || 1 === count($node->stmts) && $node->stmts[0] instanceof Node\Stmt\Nop;
  34018. if ($hasEmptyBody) {
  34019. if ($node->getEndLine() === $node->getStartLine() && isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
  34020. return;
  34021. }
  34022. $this->setLineBranch($node->getEndLine(), $node->getEndLine(), ++$this->nextBranch);
  34023. return;
  34024. }
  34025. return;
  34026. }
  34027. if ($node instanceof Node\Expr\ArrowFunction) {
  34028. $startLine = max($node->getStartLine() + 1, $node->expr->getStartLine());
  34029. $endLine = $node->expr->getEndLine();
  34030. if ($endLine < $startLine) {
  34031. return;
  34032. }
  34033. $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
  34034. return;
  34035. }
  34036. if ($node instanceof Node\Expr\Ternary) {
  34037. if (null !== $node->if && $node->getStartLine() !== $node->if->getEndLine()) {
  34038. $this->setLineBranch($node->if->getStartLine(), $node->if->getEndLine(), ++$this->nextBranch);
  34039. }
  34040. if ($node->getStartLine() !== $node->else->getEndLine()) {
  34041. $this->setLineBranch($node->else->getStartLine(), $node->else->getEndLine(), ++$this->nextBranch);
  34042. }
  34043. return;
  34044. }
  34045. if ($node instanceof Node\Expr\BinaryOp\Coalesce) {
  34046. if ($node->getStartLine() !== $node->getEndLine()) {
  34047. $this->setLineBranch($node->getEndLine(), $node->getEndLine(), ++$this->nextBranch);
  34048. }
  34049. return;
  34050. }
  34051. if ($node instanceof Node\Stmt\If_ || $node instanceof Node\Stmt\ElseIf_ || $node instanceof Node\Stmt\Case_) {
  34052. if (null === $node->cond) {
  34053. return;
  34054. }
  34055. $this->setLineBranch($node->cond->getStartLine(), $node->cond->getStartLine(), ++$this->nextBranch);
  34056. return;
  34057. }
  34058. if ($node instanceof Node\Stmt\For_) {
  34059. $startLine = null;
  34060. $endLine = null;
  34061. if ([] !== $node->init) {
  34062. $startLine = $node->init[0]->getStartLine();
  34063. end($node->init);
  34064. $endLine = current($node->init)->getEndLine();
  34065. reset($node->init);
  34066. }
  34067. if ([] !== $node->cond) {
  34068. if (null === $startLine) {
  34069. $startLine = $node->cond[0]->getStartLine();
  34070. }
  34071. end($node->cond);
  34072. $endLine = current($node->cond)->getEndLine();
  34073. reset($node->cond);
  34074. }
  34075. if ([] !== $node->loop) {
  34076. if (null === $startLine) {
  34077. $startLine = $node->loop[0]->getStartLine();
  34078. }
  34079. end($node->loop);
  34080. $endLine = current($node->loop)->getEndLine();
  34081. reset($node->loop);
  34082. }
  34083. if (null === $startLine || null === $endLine) {
  34084. return;
  34085. }
  34086. $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
  34087. return;
  34088. }
  34089. if ($node instanceof Node\Stmt\Foreach_) {
  34090. $this->setLineBranch($node->expr->getStartLine(), $node->valueVar->getEndLine(), ++$this->nextBranch);
  34091. return;
  34092. }
  34093. if ($node instanceof Node\Stmt\While_ || $node instanceof Node\Stmt\Do_) {
  34094. $this->setLineBranch($node->cond->getStartLine(), $node->cond->getEndLine(), ++$this->nextBranch);
  34095. return;
  34096. }
  34097. if ($node instanceof Node\Stmt\Catch_) {
  34098. assert([] !== $node->types);
  34099. $startLine = $node->types[0]->getStartLine();
  34100. end($node->types);
  34101. $endLine = current($node->types)->getEndLine();
  34102. $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
  34103. return;
  34104. }
  34105. if ($node instanceof Node\Expr\CallLike) {
  34106. if (isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
  34107. $branch = $this->executableLinesGroupedByBranch[$node->getStartLine()];
  34108. } else {
  34109. $branch = ++$this->nextBranch;
  34110. }
  34111. $this->setLineBranch($node->getStartLine(), $node->getEndLine(), $branch);
  34112. return;
  34113. }
  34114. if (isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
  34115. return;
  34116. }
  34117. $this->setLineBranch($node->getStartLine(), $node->getEndLine(), ++$this->nextBranch);
  34118. }
  34119. public function afterTraverse(array $nodes): void
  34120. {
  34121. $lines = explode("\n", $this->source);
  34122. foreach ($lines as $lineNumber => $line) {
  34123. $lineNumber++;
  34124. if (1 === preg_match('/^\s*$/', $line) || isset($this->commentsToCheckForUnset[$lineNumber]) && 1 === preg_match(sprintf('/^\s*%s\s*$/', preg_quote($this->commentsToCheckForUnset[$lineNumber], '/')), $line)) {
  34125. unset($this->executableLinesGroupedByBranch[$lineNumber]);
  34126. }
  34127. }
  34128. $this->executableLinesGroupedByBranch = array_diff_key($this->executableLinesGroupedByBranch, $this->unsets);
  34129. }
  34130. /**
  34131. * @psalm-return LinesType
  34132. */
  34133. public function executableLinesGroupedByBranch(): array
  34134. {
  34135. return $this->executableLinesGroupedByBranch;
  34136. }
  34137. private function setLineBranch(int $start, int $end, int $branch): void
  34138. {
  34139. foreach (range($start, $end) as $line) {
  34140. $this->executableLinesGroupedByBranch[$line] = $branch;
  34141. }
  34142. }
  34143. }
  34144. <?php
  34145. declare (strict_types=1);
  34146. /*
  34147. * This file is part of phpunit/php-code-coverage.
  34148. *
  34149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34150. *
  34151. * For the full copyright and license information, please view the LICENSE
  34152. * file that was distributed with this source code.
  34153. */
  34154. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  34155. /**
  34156. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  34157. *
  34158. * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34159. * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34160. * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34161. * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34162. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  34163. * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  34164. *
  34165. * @psalm-type LinesOfCodeType = array{
  34166. * linesOfCode: int,
  34167. * commentLinesOfCode: int,
  34168. * nonCommentLinesOfCode: int
  34169. * }
  34170. * @psalm-type LinesType = array<int, int>
  34171. */
  34172. interface FileAnalyser
  34173. {
  34174. /**
  34175. * @psalm-return array<string, CodeUnitClassType>
  34176. */
  34177. public function classesIn(string $filename): array;
  34178. /**
  34179. * @psalm-return array<string, CodeUnitTraitType>
  34180. */
  34181. public function traitsIn(string $filename): array;
  34182. /**
  34183. * @psalm-return array<string, CodeUnitFunctionType>
  34184. */
  34185. public function functionsIn(string $filename): array;
  34186. /**
  34187. * @psalm-return LinesOfCodeType
  34188. */
  34189. public function linesOfCodeFor(string $filename): array;
  34190. /**
  34191. * @psalm-return LinesType
  34192. */
  34193. public function executableLinesIn(string $filename): array;
  34194. /**
  34195. * @psalm-return LinesType
  34196. */
  34197. public function ignoredLinesFor(string $filename): array;
  34198. }
  34199. <?php
  34200. declare (strict_types=1);
  34201. /*
  34202. * This file is part of phpunit/php-code-coverage.
  34203. *
  34204. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34205. *
  34206. * For the full copyright and license information, please view the LICENSE
  34207. * file that was distributed with this source code.
  34208. */
  34209. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  34210. use function assert;
  34211. use function str_contains;
  34212. use PHPUnitPHAR\PhpParser\Node;
  34213. use PHPUnitPHAR\PhpParser\Node\Attribute;
  34214. use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
  34215. use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
  34216. use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
  34217. use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
  34218. use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
  34219. use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
  34220. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  34221. /**
  34222. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  34223. */
  34224. final class IgnoredLinesFindingVisitor extends NodeVisitorAbstract
  34225. {
  34226. /**
  34227. * @psalm-var array<int>
  34228. */
  34229. private array $ignoredLines = [];
  34230. private readonly bool $useAnnotationsForIgnoringCode;
  34231. private readonly bool $ignoreDeprecated;
  34232. public function __construct(bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecated)
  34233. {
  34234. $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
  34235. $this->ignoreDeprecated = $ignoreDeprecated;
  34236. }
  34237. public function enterNode(Node $node): void
  34238. {
  34239. if (!$node instanceof Class_ && !$node instanceof Trait_ && !$node instanceof Interface_ && !$node instanceof Enum_ && !$node instanceof ClassMethod && !$node instanceof Function_ && !$node instanceof Attribute) {
  34240. return;
  34241. }
  34242. if ($node instanceof Class_ && $node->isAnonymous()) {
  34243. return;
  34244. }
  34245. if ($node instanceof Class_ || $node instanceof Trait_ || $node instanceof Interface_ || $node instanceof Attribute) {
  34246. $this->ignoredLines[] = $node->getStartLine();
  34247. assert($node->name !== null);
  34248. // Workaround for https://github.com/nikic/PHP-Parser/issues/886
  34249. $this->ignoredLines[] = $node->name->getStartLine();
  34250. }
  34251. if (!$this->useAnnotationsForIgnoringCode) {
  34252. return;
  34253. }
  34254. if ($node instanceof Interface_) {
  34255. return;
  34256. }
  34257. if ($node instanceof Attribute && $node->name->toString() === 'PHPUnit\Framework\Attributes\CodeCoverageIgnore') {
  34258. $attributeGroup = $node->getAttribute('parent');
  34259. $attributedNode = $attributeGroup->getAttribute('parent');
  34260. for ($line = $attributedNode->getStartLine(); $line <= $attributedNode->getEndLine(); $line++) {
  34261. $this->ignoredLines[] = $line;
  34262. }
  34263. return;
  34264. }
  34265. $this->processDocComment($node);
  34266. }
  34267. /**
  34268. * @psalm-return array<int>
  34269. */
  34270. public function ignoredLines(): array
  34271. {
  34272. return $this->ignoredLines;
  34273. }
  34274. private function processDocComment(Node $node): void
  34275. {
  34276. $docComment = $node->getDocComment();
  34277. if ($docComment === null) {
  34278. return;
  34279. }
  34280. if (str_contains($docComment->getText(), '@codeCoverageIgnore')) {
  34281. for ($line = $node->getStartLine(); $line <= $node->getEndLine(); $line++) {
  34282. $this->ignoredLines[] = $line;
  34283. }
  34284. }
  34285. if ($this->ignoreDeprecated && str_contains($docComment->getText(), '@deprecated')) {
  34286. for ($line = $node->getStartLine(); $line <= $node->getEndLine(); $line++) {
  34287. $this->ignoredLines[] = $line;
  34288. }
  34289. }
  34290. }
  34291. }
  34292. <?php
  34293. declare (strict_types=1);
  34294. /*
  34295. * This file is part of phpunit/php-code-coverage.
  34296. *
  34297. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34298. *
  34299. * For the full copyright and license information, please view the LICENSE
  34300. * file that was distributed with this source code.
  34301. */
  34302. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
  34303. use function array_merge;
  34304. use function array_unique;
  34305. use function assert;
  34306. use function file_get_contents;
  34307. use function is_array;
  34308. use function max;
  34309. use function range;
  34310. use function sort;
  34311. use function sprintf;
  34312. use function substr_count;
  34313. use function token_get_all;
  34314. use function trim;
  34315. use PHPUnitPHAR\PhpParser\Error;
  34316. use PHPUnitPHAR\PhpParser\NodeTraverser;
  34317. use PHPUnitPHAR\PhpParser\NodeVisitor\NameResolver;
  34318. use PHPUnitPHAR\PhpParser\NodeVisitor\ParentConnectingVisitor;
  34319. use PHPUnitPHAR\PhpParser\ParserFactory;
  34320. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ParserException;
  34321. use PHPUnitPHAR\SebastianBergmann\LinesOfCode\LineCountingVisitor;
  34322. /**
  34323. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  34324. *
  34325. * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34326. * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34327. * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34328. * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
  34329. * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  34330. * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
  34331. */
  34332. final class ParsingFileAnalyser implements FileAnalyser
  34333. {
  34334. /**
  34335. * @psalm-var array<string, array<string, CodeUnitClassType>>
  34336. */
  34337. private array $classes = [];
  34338. /**
  34339. * @psalm-var array<string, array<string, CodeUnitTraitType>>
  34340. */
  34341. private array $traits = [];
  34342. /**
  34343. * @psalm-var array<string, array<string, CodeUnitFunctionType>>
  34344. */
  34345. private array $functions = [];
  34346. /**
  34347. * @var array<string, LinesOfCodeType>
  34348. */
  34349. private array $linesOfCode = [];
  34350. /**
  34351. * @var array<string, LinesType>
  34352. */
  34353. private array $ignoredLines = [];
  34354. /**
  34355. * @var array<string, LinesType>
  34356. */
  34357. private array $executableLines = [];
  34358. private readonly bool $useAnnotationsForIgnoringCode;
  34359. private readonly bool $ignoreDeprecatedCode;
  34360. public function __construct(bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode)
  34361. {
  34362. $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
  34363. $this->ignoreDeprecatedCode = $ignoreDeprecatedCode;
  34364. }
  34365. public function classesIn(string $filename): array
  34366. {
  34367. $this->analyse($filename);
  34368. return $this->classes[$filename];
  34369. }
  34370. public function traitsIn(string $filename): array
  34371. {
  34372. $this->analyse($filename);
  34373. return $this->traits[$filename];
  34374. }
  34375. public function functionsIn(string $filename): array
  34376. {
  34377. $this->analyse($filename);
  34378. return $this->functions[$filename];
  34379. }
  34380. public function linesOfCodeFor(string $filename): array
  34381. {
  34382. $this->analyse($filename);
  34383. return $this->linesOfCode[$filename];
  34384. }
  34385. public function executableLinesIn(string $filename): array
  34386. {
  34387. $this->analyse($filename);
  34388. return $this->executableLines[$filename];
  34389. }
  34390. public function ignoredLinesFor(string $filename): array
  34391. {
  34392. $this->analyse($filename);
  34393. return $this->ignoredLines[$filename];
  34394. }
  34395. /**
  34396. * @throws ParserException
  34397. */
  34398. private function analyse(string $filename): void
  34399. {
  34400. if (isset($this->classes[$filename])) {
  34401. return;
  34402. }
  34403. $source = file_get_contents($filename);
  34404. $linesOfCode = max(substr_count($source, "\n") + 1, substr_count($source, "\r") + 1);
  34405. if ($linesOfCode === 0 && !empty($source)) {
  34406. $linesOfCode = 1;
  34407. }
  34408. assert($linesOfCode > 0);
  34409. $parser = (new ParserFactory())->createForHostVersion();
  34410. try {
  34411. $nodes = $parser->parse($source);
  34412. assert($nodes !== null);
  34413. $traverser = new NodeTraverser();
  34414. $codeUnitFindingVisitor = new CodeUnitFindingVisitor();
  34415. $lineCountingVisitor = new LineCountingVisitor($linesOfCode);
  34416. $ignoredLinesFindingVisitor = new IgnoredLinesFindingVisitor($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
  34417. $executableLinesFindingVisitor = new ExecutableLinesFindingVisitor($source);
  34418. $traverser->addVisitor(new NameResolver());
  34419. $traverser->addVisitor(new ParentConnectingVisitor());
  34420. $traverser->addVisitor($codeUnitFindingVisitor);
  34421. $traverser->addVisitor($lineCountingVisitor);
  34422. $traverser->addVisitor($ignoredLinesFindingVisitor);
  34423. $traverser->addVisitor($executableLinesFindingVisitor);
  34424. /* @noinspection UnusedFunctionResultInspection */
  34425. $traverser->traverse($nodes);
  34426. // @codeCoverageIgnoreStart
  34427. } catch (Error $error) {
  34428. throw new ParserException(sprintf('Cannot parse %s: %s', $filename, $error->getMessage()), $error->getCode(), $error);
  34429. }
  34430. // @codeCoverageIgnoreEnd
  34431. $this->classes[$filename] = $codeUnitFindingVisitor->classes();
  34432. $this->traits[$filename] = $codeUnitFindingVisitor->traits();
  34433. $this->functions[$filename] = $codeUnitFindingVisitor->functions();
  34434. $this->executableLines[$filename] = $executableLinesFindingVisitor->executableLinesGroupedByBranch();
  34435. $this->ignoredLines[$filename] = [];
  34436. $this->findLinesIgnoredByLineBasedAnnotations($filename, $source, $this->useAnnotationsForIgnoringCode);
  34437. $this->ignoredLines[$filename] = array_unique(array_merge($this->ignoredLines[$filename], $ignoredLinesFindingVisitor->ignoredLines()));
  34438. sort($this->ignoredLines[$filename]);
  34439. $result = $lineCountingVisitor->result();
  34440. $this->linesOfCode[$filename] = ['linesOfCode' => $result->linesOfCode(), 'commentLinesOfCode' => $result->commentLinesOfCode(), 'nonCommentLinesOfCode' => $result->nonCommentLinesOfCode()];
  34441. }
  34442. private function findLinesIgnoredByLineBasedAnnotations(string $filename, string $source, bool $useAnnotationsForIgnoringCode): void
  34443. {
  34444. if (!$useAnnotationsForIgnoringCode) {
  34445. return;
  34446. }
  34447. $start = \false;
  34448. foreach (token_get_all($source) as $token) {
  34449. if (!is_array($token) || !(\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0])) {
  34450. continue;
  34451. }
  34452. $comment = trim($token[1]);
  34453. if ($comment === '// @codeCoverageIgnore' || $comment === '//@codeCoverageIgnore') {
  34454. $this->ignoredLines[$filename][] = $token[2];
  34455. continue;
  34456. }
  34457. if ($comment === '// @codeCoverageIgnoreStart' || $comment === '//@codeCoverageIgnoreStart') {
  34458. $start = $token[2];
  34459. continue;
  34460. }
  34461. if ($comment === '// @codeCoverageIgnoreEnd' || $comment === '//@codeCoverageIgnoreEnd') {
  34462. if (\false === $start) {
  34463. $start = $token[2];
  34464. }
  34465. $this->ignoredLines[$filename] = array_merge($this->ignoredLines[$filename], range($start, $token[2]));
  34466. }
  34467. }
  34468. }
  34469. }
  34470. <?php
  34471. declare (strict_types=1);
  34472. /*
  34473. * This file is part of phpunit/php-code-coverage.
  34474. *
  34475. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34476. *
  34477. * For the full copyright and license information, please view the LICENSE
  34478. * file that was distributed with this source code.
  34479. */
  34480. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34481. /**
  34482. * @psalm-immutable
  34483. */
  34484. abstract class Known extends TestSize
  34485. {
  34486. /**
  34487. * @psalm-assert-if-true Known $this
  34488. */
  34489. public function isKnown(): bool
  34490. {
  34491. return \true;
  34492. }
  34493. abstract public function isGreaterThan(self $other): bool;
  34494. }
  34495. <?php
  34496. declare (strict_types=1);
  34497. /*
  34498. * This file is part of phpunit/php-code-coverage.
  34499. *
  34500. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34501. *
  34502. * For the full copyright and license information, please view the LICENSE
  34503. * file that was distributed with this source code.
  34504. */
  34505. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34506. /**
  34507. * @psalm-immutable
  34508. */
  34509. final class Large extends Known
  34510. {
  34511. /**
  34512. * @psalm-assert-if-true Large $this
  34513. */
  34514. public function isLarge(): bool
  34515. {
  34516. return \true;
  34517. }
  34518. public function isGreaterThan(TestSize $other): bool
  34519. {
  34520. return !$other->isLarge();
  34521. }
  34522. public function asString(): string
  34523. {
  34524. return 'large';
  34525. }
  34526. }
  34527. <?php
  34528. declare (strict_types=1);
  34529. /*
  34530. * This file is part of phpunit/php-code-coverage.
  34531. *
  34532. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34533. *
  34534. * For the full copyright and license information, please view the LICENSE
  34535. * file that was distributed with this source code.
  34536. */
  34537. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34538. /**
  34539. * @psalm-immutable
  34540. */
  34541. final class Medium extends Known
  34542. {
  34543. /**
  34544. * @psalm-assert-if-true Medium $this
  34545. */
  34546. public function isMedium(): bool
  34547. {
  34548. return \true;
  34549. }
  34550. public function isGreaterThan(TestSize $other): bool
  34551. {
  34552. return $other->isSmall();
  34553. }
  34554. public function asString(): string
  34555. {
  34556. return 'medium';
  34557. }
  34558. }
  34559. <?php
  34560. declare (strict_types=1);
  34561. /*
  34562. * This file is part of phpunit/php-code-coverage.
  34563. *
  34564. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34565. *
  34566. * For the full copyright and license information, please view the LICENSE
  34567. * file that was distributed with this source code.
  34568. */
  34569. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34570. /**
  34571. * @psalm-immutable
  34572. */
  34573. final class Small extends Known
  34574. {
  34575. /**
  34576. * @psalm-assert-if-true Small $this
  34577. */
  34578. public function isSmall(): bool
  34579. {
  34580. return \true;
  34581. }
  34582. public function isGreaterThan(TestSize $other): bool
  34583. {
  34584. return \false;
  34585. }
  34586. public function asString(): string
  34587. {
  34588. return 'small';
  34589. }
  34590. }
  34591. <?php
  34592. declare (strict_types=1);
  34593. /*
  34594. * This file is part of phpunit/php-code-coverage.
  34595. *
  34596. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34597. *
  34598. * For the full copyright and license information, please view the LICENSE
  34599. * file that was distributed with this source code.
  34600. */
  34601. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34602. /**
  34603. * @psalm-immutable
  34604. */
  34605. abstract class TestSize
  34606. {
  34607. public static function unknown(): self
  34608. {
  34609. return new Unknown();
  34610. }
  34611. public static function small(): self
  34612. {
  34613. return new Small();
  34614. }
  34615. public static function medium(): self
  34616. {
  34617. return new Medium();
  34618. }
  34619. public static function large(): self
  34620. {
  34621. return new Large();
  34622. }
  34623. /**
  34624. * @psalm-assert-if-true Known $this
  34625. */
  34626. public function isKnown(): bool
  34627. {
  34628. return \false;
  34629. }
  34630. /**
  34631. * @psalm-assert-if-true Unknown $this
  34632. */
  34633. public function isUnknown(): bool
  34634. {
  34635. return \false;
  34636. }
  34637. /**
  34638. * @psalm-assert-if-true Small $this
  34639. */
  34640. public function isSmall(): bool
  34641. {
  34642. return \false;
  34643. }
  34644. /**
  34645. * @psalm-assert-if-true Medium $this
  34646. */
  34647. public function isMedium(): bool
  34648. {
  34649. return \false;
  34650. }
  34651. /**
  34652. * @psalm-assert-if-true Large $this
  34653. */
  34654. public function isLarge(): bool
  34655. {
  34656. return \false;
  34657. }
  34658. abstract public function asString(): string;
  34659. }
  34660. <?php
  34661. declare (strict_types=1);
  34662. /*
  34663. * This file is part of phpunit/php-code-coverage.
  34664. *
  34665. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34666. *
  34667. * For the full copyright and license information, please view the LICENSE
  34668. * file that was distributed with this source code.
  34669. */
  34670. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
  34671. /**
  34672. * @psalm-immutable
  34673. */
  34674. final class Unknown extends TestSize
  34675. {
  34676. /**
  34677. * @psalm-assert-if-true Unknown $this
  34678. */
  34679. public function isUnknown(): bool
  34680. {
  34681. return \true;
  34682. }
  34683. public function asString(): string
  34684. {
  34685. return 'unknown';
  34686. }
  34687. }
  34688. <?php
  34689. declare (strict_types=1);
  34690. /*
  34691. * This file is part of phpunit/php-code-coverage.
  34692. *
  34693. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34694. *
  34695. * For the full copyright and license information, please view the LICENSE
  34696. * file that was distributed with this source code.
  34697. */
  34698. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
  34699. /**
  34700. * @psalm-immutable
  34701. */
  34702. final class Failure extends Known
  34703. {
  34704. /**
  34705. * @psalm-assert-if-true Failure $this
  34706. */
  34707. public function isFailure(): bool
  34708. {
  34709. return \true;
  34710. }
  34711. public function asString(): string
  34712. {
  34713. return 'failure';
  34714. }
  34715. }
  34716. <?php
  34717. declare (strict_types=1);
  34718. /*
  34719. * This file is part of phpunit/php-code-coverage.
  34720. *
  34721. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34722. *
  34723. * For the full copyright and license information, please view the LICENSE
  34724. * file that was distributed with this source code.
  34725. */
  34726. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
  34727. /**
  34728. * @psalm-immutable
  34729. */
  34730. abstract class Known extends TestStatus
  34731. {
  34732. /**
  34733. * @psalm-assert-if-true Known $this
  34734. */
  34735. public function isKnown(): bool
  34736. {
  34737. return \true;
  34738. }
  34739. }
  34740. <?php
  34741. declare (strict_types=1);
  34742. /*
  34743. * This file is part of phpunit/php-code-coverage.
  34744. *
  34745. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34746. *
  34747. * For the full copyright and license information, please view the LICENSE
  34748. * file that was distributed with this source code.
  34749. */
  34750. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
  34751. /**
  34752. * @psalm-immutable
  34753. */
  34754. final class Success extends Known
  34755. {
  34756. /**
  34757. * @psalm-assert-if-true Success $this
  34758. */
  34759. public function isSuccess(): bool
  34760. {
  34761. return \true;
  34762. }
  34763. public function asString(): string
  34764. {
  34765. return 'success';
  34766. }
  34767. }
  34768. <?php
  34769. declare (strict_types=1);
  34770. /*
  34771. * This file is part of phpunit/php-code-coverage.
  34772. *
  34773. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34774. *
  34775. * For the full copyright and license information, please view the LICENSE
  34776. * file that was distributed with this source code.
  34777. */
  34778. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
  34779. /**
  34780. * @psalm-immutable
  34781. */
  34782. abstract class TestStatus
  34783. {
  34784. public static function unknown(): self
  34785. {
  34786. return new Unknown();
  34787. }
  34788. public static function success(): self
  34789. {
  34790. return new Success();
  34791. }
  34792. public static function failure(): self
  34793. {
  34794. return new Failure();
  34795. }
  34796. /**
  34797. * @psalm-assert-if-true Known $this
  34798. */
  34799. public function isKnown(): bool
  34800. {
  34801. return \false;
  34802. }
  34803. /**
  34804. * @psalm-assert-if-true Unknown $this
  34805. */
  34806. public function isUnknown(): bool
  34807. {
  34808. return \false;
  34809. }
  34810. /**
  34811. * @psalm-assert-if-true Success $this
  34812. */
  34813. public function isSuccess(): bool
  34814. {
  34815. return \false;
  34816. }
  34817. /**
  34818. * @psalm-assert-if-true Failure $this
  34819. */
  34820. public function isFailure(): bool
  34821. {
  34822. return \false;
  34823. }
  34824. abstract public function asString(): string;
  34825. }
  34826. <?php
  34827. declare (strict_types=1);
  34828. /*
  34829. * This file is part of phpunit/php-code-coverage.
  34830. *
  34831. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34832. *
  34833. * For the full copyright and license information, please view the LICENSE
  34834. * file that was distributed with this source code.
  34835. */
  34836. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
  34837. /**
  34838. * @psalm-immutable
  34839. */
  34840. final class Unknown extends TestStatus
  34841. {
  34842. /**
  34843. * @psalm-assert-if-true Unknown $this
  34844. */
  34845. public function isUnknown(): bool
  34846. {
  34847. return \true;
  34848. }
  34849. public function asString(): string
  34850. {
  34851. return 'unknown';
  34852. }
  34853. }
  34854. <?php
  34855. declare (strict_types=1);
  34856. /*
  34857. * This file is part of phpunit/php-code-coverage.
  34858. *
  34859. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34860. *
  34861. * For the full copyright and license information, please view the LICENSE
  34862. * file that was distributed with this source code.
  34863. */
  34864. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
  34865. use function is_dir;
  34866. use function mkdir;
  34867. use function sprintf;
  34868. /**
  34869. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  34870. */
  34871. final class Filesystem
  34872. {
  34873. /**
  34874. * @throws DirectoryCouldNotBeCreatedException
  34875. */
  34876. public static function createDirectory(string $directory): void
  34877. {
  34878. $success = !(!is_dir($directory) && !@mkdir($directory, 0777, \true) && !is_dir($directory));
  34879. if (!$success) {
  34880. throw new DirectoryCouldNotBeCreatedException(sprintf('Directory "%s" could not be created', $directory));
  34881. }
  34882. }
  34883. }
  34884. <?php
  34885. declare (strict_types=1);
  34886. /*
  34887. * This file is part of phpunit/php-code-coverage.
  34888. *
  34889. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34890. *
  34891. * For the full copyright and license information, please view the LICENSE
  34892. * file that was distributed with this source code.
  34893. */
  34894. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
  34895. use function sprintf;
  34896. /**
  34897. * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
  34898. */
  34899. final class Percentage
  34900. {
  34901. private readonly float $fraction;
  34902. private readonly float $total;
  34903. public static function fromFractionAndTotal(float $fraction, float $total): self
  34904. {
  34905. return new self($fraction, $total);
  34906. }
  34907. private function __construct(float $fraction, float $total)
  34908. {
  34909. $this->fraction = $fraction;
  34910. $this->total = $total;
  34911. }
  34912. public function asFloat(): float
  34913. {
  34914. if ($this->total > 0) {
  34915. return $this->fraction / $this->total * 100;
  34916. }
  34917. return 100.0;
  34918. }
  34919. public function asString(): string
  34920. {
  34921. if ($this->total > 0) {
  34922. return sprintf('%01.2F%%', $this->asFloat());
  34923. }
  34924. return '';
  34925. }
  34926. public function asFixedWidthString(): string
  34927. {
  34928. if ($this->total > 0) {
  34929. return sprintf('%6.2F%%', $this->asFloat());
  34930. }
  34931. return '';
  34932. }
  34933. }
  34934. <?php
  34935. declare (strict_types=1);
  34936. /*
  34937. * This file is part of phpunit/php-code-coverage.
  34938. *
  34939. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34940. *
  34941. * For the full copyright and license information, please view the LICENSE
  34942. * file that was distributed with this source code.
  34943. */
  34944. namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
  34945. use function dirname;
  34946. use PHPUnitPHAR\SebastianBergmann\Version as VersionId;
  34947. final class Version
  34948. {
  34949. private static string $version = '';
  34950. public static function id(): string
  34951. {
  34952. if (self::$version === '') {
  34953. self::$version = (new VersionId('10.1.16', dirname(__DIR__)))->asString();
  34954. }
  34955. return self::$version;
  34956. }
  34957. }
  34958. <?php
  34959. declare (strict_types=1);
  34960. /*
  34961. * This file is part of phpunit/php-file-iterator.
  34962. *
  34963. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34964. *
  34965. * For the full copyright and license information, please view the LICENSE
  34966. * file that was distributed with this source code.
  34967. */
  34968. namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
  34969. use function assert;
  34970. use function str_starts_with;
  34971. use RecursiveDirectoryIterator;
  34972. use RecursiveFilterIterator;
  34973. use SplFileInfo;
  34974. /**
  34975. * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
  34976. */
  34977. final class ExcludeIterator extends RecursiveFilterIterator
  34978. {
  34979. /**
  34980. * @psalm-var list<string>
  34981. */
  34982. private array $exclude;
  34983. /**
  34984. * @psalm-param list<string> $exclude
  34985. */
  34986. public function __construct(RecursiveDirectoryIterator $iterator, array $exclude)
  34987. {
  34988. parent::__construct($iterator);
  34989. $this->exclude = $exclude;
  34990. }
  34991. public function accept(): bool
  34992. {
  34993. $current = $this->current();
  34994. assert($current instanceof SplFileInfo);
  34995. $path = $current->getRealPath();
  34996. if ($path === \false) {
  34997. return \false;
  34998. }
  34999. foreach ($this->exclude as $exclude) {
  35000. if (str_starts_with($path, $exclude)) {
  35001. return \false;
  35002. }
  35003. }
  35004. return \true;
  35005. }
  35006. public function hasChildren(): bool
  35007. {
  35008. return $this->getInnerIterator()->hasChildren();
  35009. }
  35010. public function getChildren(): self
  35011. {
  35012. return new self($this->getInnerIterator()->getChildren(), $this->exclude);
  35013. }
  35014. public function getInnerIterator(): RecursiveDirectoryIterator
  35015. {
  35016. $innerIterator = parent::getInnerIterator();
  35017. assert($innerIterator instanceof RecursiveDirectoryIterator);
  35018. return $innerIterator;
  35019. }
  35020. }
  35021. <?php
  35022. declare (strict_types=1);
  35023. /*
  35024. * This file is part of phpunit/php-file-iterator.
  35025. *
  35026. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35027. *
  35028. * For the full copyright and license information, please view the LICENSE
  35029. * file that was distributed with this source code.
  35030. */
  35031. namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
  35032. use function array_unique;
  35033. use function assert;
  35034. use function sort;
  35035. use SplFileInfo;
  35036. /**
  35037. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  35038. */
  35039. final class Facade
  35040. {
  35041. /**
  35042. * @psalm-param list<non-empty-string>|non-empty-string $paths
  35043. * @psalm-param list<non-empty-string>|string $suffixes
  35044. * @psalm-param list<non-empty-string>|string $prefixes
  35045. * @psalm-param list<non-empty-string> $exclude
  35046. *
  35047. * @psalm-return list<non-empty-string>
  35048. */
  35049. public function getFilesAsArray(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): array
  35050. {
  35051. $iterator = (new Factory())->getFileIterator($paths, $suffixes, $prefixes, $exclude);
  35052. $files = [];
  35053. foreach ($iterator as $file) {
  35054. assert($file instanceof SplFileInfo);
  35055. $file = $file->getRealPath();
  35056. if ($file) {
  35057. $files[] = $file;
  35058. }
  35059. }
  35060. $files = array_unique($files);
  35061. sort($files);
  35062. return $files;
  35063. }
  35064. }
  35065. <?php
  35066. declare (strict_types=1);
  35067. /*
  35068. * This file is part of phpunit/php-file-iterator.
  35069. *
  35070. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35071. *
  35072. * For the full copyright and license information, please view the LICENSE
  35073. * file that was distributed with this source code.
  35074. */
  35075. namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
  35076. use const GLOB_ONLYDIR;
  35077. use function array_filter;
  35078. use function array_map;
  35079. use function array_merge;
  35080. use function array_values;
  35081. use function glob;
  35082. use function is_dir;
  35083. use function is_string;
  35084. use function realpath;
  35085. use AppendIterator;
  35086. use FilesystemIterator;
  35087. use RecursiveDirectoryIterator;
  35088. use RecursiveIteratorIterator;
  35089. /**
  35090. * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
  35091. */
  35092. final class Factory
  35093. {
  35094. /**
  35095. * @psalm-param list<non-empty-string>|non-empty-string $paths
  35096. * @psalm-param list<non-empty-string>|string $suffixes
  35097. * @psalm-param list<non-empty-string>|string $prefixes
  35098. * @psalm-param list<non-empty-string> $exclude
  35099. */
  35100. public function getFileIterator(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): AppendIterator
  35101. {
  35102. if (is_string($paths)) {
  35103. $paths = [$paths];
  35104. }
  35105. $paths = $this->resolveWildcards($paths);
  35106. $exclude = $this->resolveWildcards($exclude);
  35107. if (is_string($prefixes)) {
  35108. if ($prefixes !== '') {
  35109. $prefixes = [$prefixes];
  35110. } else {
  35111. $prefixes = [];
  35112. }
  35113. }
  35114. if (is_string($suffixes)) {
  35115. if ($suffixes !== '') {
  35116. $suffixes = [$suffixes];
  35117. } else {
  35118. $suffixes = [];
  35119. }
  35120. }
  35121. $iterator = new AppendIterator();
  35122. foreach ($paths as $path) {
  35123. if (is_dir($path)) {
  35124. $iterator->append(new Iterator($path, new RecursiveIteratorIterator(new ExcludeIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::SKIP_DOTS), $exclude)), $suffixes, $prefixes));
  35125. }
  35126. }
  35127. return $iterator;
  35128. }
  35129. /**
  35130. * @psalm-param list<non-empty-string> $paths
  35131. *
  35132. * @psalm-return list<non-empty-string>
  35133. */
  35134. private function resolveWildcards(array $paths): array
  35135. {
  35136. $_paths = [[]];
  35137. foreach ($paths as $path) {
  35138. if ($locals = glob($path, GLOB_ONLYDIR)) {
  35139. $_paths[] = array_map('\realpath', $locals);
  35140. } else {
  35141. // @codeCoverageIgnoreStart
  35142. $_paths[] = [realpath($path)];
  35143. // @codeCoverageIgnoreEnd
  35144. }
  35145. }
  35146. return array_values(array_filter(array_merge(...$_paths)));
  35147. }
  35148. }
  35149. <?php
  35150. declare (strict_types=1);
  35151. /*
  35152. * This file is part of phpunit/php-file-iterator.
  35153. *
  35154. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35155. *
  35156. * For the full copyright and license information, please view the LICENSE
  35157. * file that was distributed with this source code.
  35158. */
  35159. namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
  35160. use function assert;
  35161. use function preg_match;
  35162. use function realpath;
  35163. use function str_ends_with;
  35164. use function str_replace;
  35165. use function str_starts_with;
  35166. use AppendIterator;
  35167. use FilterIterator;
  35168. use SplFileInfo;
  35169. /**
  35170. * @template-extends FilterIterator<int, string, AppendIterator>
  35171. *
  35172. * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
  35173. */
  35174. final class Iterator extends FilterIterator
  35175. {
  35176. public const PREFIX = 0;
  35177. public const SUFFIX = 1;
  35178. private string|false $basePath;
  35179. /**
  35180. * @psalm-var list<string>
  35181. */
  35182. private array $suffixes;
  35183. /**
  35184. * @psalm-var list<string>
  35185. */
  35186. private array $prefixes;
  35187. /**
  35188. * @psalm-param list<string> $suffixes
  35189. * @psalm-param list<string> $prefixes
  35190. */
  35191. public function __construct(string $basePath, \Iterator $iterator, array $suffixes = [], array $prefixes = [])
  35192. {
  35193. $this->basePath = realpath($basePath);
  35194. $this->prefixes = $prefixes;
  35195. $this->suffixes = $suffixes;
  35196. parent::__construct($iterator);
  35197. }
  35198. public function accept(): bool
  35199. {
  35200. $current = $this->getInnerIterator()->current();
  35201. assert($current instanceof SplFileInfo);
  35202. $filename = $current->getFilename();
  35203. $realPath = $current->getRealPath();
  35204. if ($realPath === \false) {
  35205. // @codeCoverageIgnoreStart
  35206. return \false;
  35207. // @codeCoverageIgnoreEnd
  35208. }
  35209. return $this->acceptPath($realPath) && $this->acceptPrefix($filename) && $this->acceptSuffix($filename);
  35210. }
  35211. private function acceptPath(string $path): bool
  35212. {
  35213. // Filter files in hidden directories by checking path that is relative to the base path.
  35214. if (preg_match('=/\.[^/]*/=', str_replace((string) $this->basePath, '', $path))) {
  35215. return \false;
  35216. }
  35217. return \true;
  35218. }
  35219. private function acceptPrefix(string $filename): bool
  35220. {
  35221. return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
  35222. }
  35223. private function acceptSuffix(string $filename): bool
  35224. {
  35225. return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
  35226. }
  35227. /**
  35228. * @psalm-param list<string> $subStrings
  35229. */
  35230. private function acceptSubString(string $filename, array $subStrings, int $type): bool
  35231. {
  35232. if (empty($subStrings)) {
  35233. return \true;
  35234. }
  35235. foreach ($subStrings as $string) {
  35236. if ($type === self::PREFIX && str_starts_with($filename, $string) || $type === self::SUFFIX && str_ends_with($filename, $string)) {
  35237. return \true;
  35238. }
  35239. }
  35240. return \false;
  35241. }
  35242. }
  35243. BSD 3-Clause License
  35244. Copyright (c) 2009-2023, Sebastian Bergmann
  35245. All rights reserved.
  35246. Redistribution and use in source and binary forms, with or without
  35247. modification, are permitted provided that the following conditions are met:
  35248. 1. Redistributions of source code must retain the above copyright notice, this
  35249. list of conditions and the following disclaimer.
  35250. 2. Redistributions in binary form must reproduce the above copyright notice,
  35251. this list of conditions and the following disclaimer in the documentation
  35252. and/or other materials provided with the distribution.
  35253. 3. Neither the name of the copyright holder nor the names of its
  35254. contributors may be used to endorse or promote products derived from
  35255. this software without specific prior written permission.
  35256. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  35257. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35258. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35259. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  35260. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35261. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  35262. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35263. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35264. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35265. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35266. <?php
  35267. declare (strict_types=1);
  35268. /*
  35269. * This file is part of phpunit/php-invoker.
  35270. *
  35271. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35272. *
  35273. * For the full copyright and license information, please view the LICENSE
  35274. * file that was distributed with this source code.
  35275. */
  35276. namespace PHPUnitPHAR\SebastianBergmann\Invoker;
  35277. use const SIGALRM;
  35278. use function call_user_func_array;
  35279. use function function_exists;
  35280. use function pcntl_alarm;
  35281. use function pcntl_async_signals;
  35282. use function pcntl_signal;
  35283. use function sprintf;
  35284. use Throwable;
  35285. final class Invoker
  35286. {
  35287. private int $timeout;
  35288. /**
  35289. * @throws Throwable
  35290. */
  35291. public function invoke(callable $callable, array $arguments, int $timeout): mixed
  35292. {
  35293. if (!$this->canInvokeWithTimeout()) {
  35294. throw new ProcessControlExtensionNotLoadedException('The pcntl (process control) extension for PHP is required');
  35295. }
  35296. pcntl_signal(SIGALRM, function (): void {
  35297. throw new TimeoutException(sprintf('Execution aborted after %d second%s', $this->timeout, $this->timeout === 1 ? '' : 's'));
  35298. }, \true);
  35299. $this->timeout = $timeout;
  35300. pcntl_async_signals(\true);
  35301. pcntl_alarm($timeout);
  35302. try {
  35303. return call_user_func_array($callable, $arguments);
  35304. } finally {
  35305. pcntl_alarm(0);
  35306. }
  35307. }
  35308. public function canInvokeWithTimeout(): bool
  35309. {
  35310. return function_exists('pcntl_signal') && function_exists('pcntl_async_signals') && function_exists('pcntl_alarm');
  35311. }
  35312. }
  35313. <?php
  35314. declare (strict_types=1);
  35315. /*
  35316. * This file is part of phpunit/php-invoker.
  35317. *
  35318. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35319. *
  35320. * For the full copyright and license information, please view the LICENSE
  35321. * file that was distributed with this source code.
  35322. */
  35323. namespace PHPUnitPHAR\SebastianBergmann\Invoker;
  35324. use Throwable;
  35325. interface Exception extends Throwable
  35326. {
  35327. }
  35328. <?php
  35329. declare (strict_types=1);
  35330. /*
  35331. * This file is part of phpunit/php-invoker.
  35332. *
  35333. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35334. *
  35335. * For the full copyright and license information, please view the LICENSE
  35336. * file that was distributed with this source code.
  35337. */
  35338. namespace PHPUnitPHAR\SebastianBergmann\Invoker;
  35339. use RuntimeException;
  35340. final class ProcessControlExtensionNotLoadedException extends RuntimeException implements Exception
  35341. {
  35342. }
  35343. <?php
  35344. declare (strict_types=1);
  35345. /*
  35346. * This file is part of phpunit/php-invoker.
  35347. *
  35348. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35349. *
  35350. * For the full copyright and license information, please view the LICENSE
  35351. * file that was distributed with this source code.
  35352. */
  35353. namespace PHPUnitPHAR\SebastianBergmann\Invoker;
  35354. use RuntimeException;
  35355. final class TimeoutException extends RuntimeException implements Exception
  35356. {
  35357. }
  35358. BSD 3-Clause License
  35359. Copyright (c) 2009-2023, Sebastian Bergmann
  35360. All rights reserved.
  35361. Redistribution and use in source and binary forms, with or without
  35362. modification, are permitted provided that the following conditions are met:
  35363. 1. Redistributions of source code must retain the above copyright notice, this
  35364. list of conditions and the following disclaimer.
  35365. 2. Redistributions in binary form must reproduce the above copyright notice,
  35366. this list of conditions and the following disclaimer in the documentation
  35367. and/or other materials provided with the distribution.
  35368. 3. Neither the name of the copyright holder nor the names of its
  35369. contributors may be used to endorse or promote products derived from
  35370. this software without specific prior written permission.
  35371. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  35372. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35373. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35374. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  35375. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35376. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  35377. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35378. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35379. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35380. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35381. <?php
  35382. declare (strict_types=1);
  35383. /*
  35384. * This file is part of phpunit/php-text-template.
  35385. *
  35386. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35387. *
  35388. * For the full copyright and license information, please view the LICENSE
  35389. * file that was distributed with this source code.
  35390. */
  35391. namespace PHPUnitPHAR\SebastianBergmann\Template;
  35392. use function array_keys;
  35393. use function array_merge;
  35394. use function file_get_contents;
  35395. use function file_put_contents;
  35396. use function is_file;
  35397. use function sprintf;
  35398. use function str_replace;
  35399. final class Template
  35400. {
  35401. private string $template = '';
  35402. private string $openDelimiter;
  35403. private string $closeDelimiter;
  35404. /**
  35405. * @psalm-var array<string,string>
  35406. */
  35407. private array $values = [];
  35408. /**
  35409. * @throws InvalidArgumentException
  35410. */
  35411. public function __construct(string $file = '', string $openDelimiter = '{', string $closeDelimiter = '}')
  35412. {
  35413. $this->setFile($file);
  35414. $this->openDelimiter = $openDelimiter;
  35415. $this->closeDelimiter = $closeDelimiter;
  35416. }
  35417. /**
  35418. * @throws InvalidArgumentException
  35419. */
  35420. public function setFile(string $file): void
  35421. {
  35422. if (is_file($file)) {
  35423. $this->template = file_get_contents($file);
  35424. return;
  35425. }
  35426. $distFile = $file . '.dist';
  35427. if (is_file($distFile)) {
  35428. $this->template = file_get_contents($distFile);
  35429. return;
  35430. }
  35431. throw new InvalidArgumentException(sprintf('Failed to load template "%s"', $file));
  35432. }
  35433. /**
  35434. * @psalm-param array<string,string> $values
  35435. */
  35436. public function setVar(array $values, bool $merge = \true): void
  35437. {
  35438. if (!$merge || empty($this->values)) {
  35439. $this->values = $values;
  35440. return;
  35441. }
  35442. $this->values = array_merge($this->values, $values);
  35443. }
  35444. public function render(): string
  35445. {
  35446. $keys = [];
  35447. foreach (array_keys($this->values) as $key) {
  35448. $keys[] = $this->openDelimiter . $key . $this->closeDelimiter;
  35449. }
  35450. return str_replace($keys, $this->values, $this->template);
  35451. }
  35452. /**
  35453. * @codeCoverageIgnore
  35454. */
  35455. public function renderTo(string $target): void
  35456. {
  35457. if (!@file_put_contents($target, $this->render())) {
  35458. throw new RuntimeException(sprintf('Writing rendered result to "%s" failed', $target));
  35459. }
  35460. }
  35461. }
  35462. <?php
  35463. declare (strict_types=1);
  35464. /*
  35465. * This file is part of phpunit/php-text-template.
  35466. *
  35467. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35468. *
  35469. * For the full copyright and license information, please view the LICENSE
  35470. * file that was distributed with this source code.
  35471. */
  35472. namespace PHPUnitPHAR\SebastianBergmann\Template;
  35473. use Throwable;
  35474. interface Exception extends Throwable
  35475. {
  35476. }
  35477. <?php
  35478. declare (strict_types=1);
  35479. /*
  35480. * This file is part of phpunit/php-text-template.
  35481. *
  35482. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35483. *
  35484. * For the full copyright and license information, please view the LICENSE
  35485. * file that was distributed with this source code.
  35486. */
  35487. namespace PHPUnitPHAR\SebastianBergmann\Template;
  35488. final class InvalidArgumentException extends \InvalidArgumentException implements Exception
  35489. {
  35490. }
  35491. <?php
  35492. declare (strict_types=1);
  35493. /*
  35494. * This file is part of phpunit/php-text-template.
  35495. *
  35496. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35497. *
  35498. * For the full copyright and license information, please view the LICENSE
  35499. * file that was distributed with this source code.
  35500. */
  35501. namespace PHPUnitPHAR\SebastianBergmann\Template;
  35502. use InvalidArgumentException;
  35503. final class RuntimeException extends InvalidArgumentException implements Exception
  35504. {
  35505. }
  35506. <?php
  35507. declare (strict_types=1);
  35508. /*
  35509. * This file is part of phpunit/php-timer.
  35510. *
  35511. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35512. *
  35513. * For the full copyright and license information, please view the LICENSE
  35514. * file that was distributed with this source code.
  35515. */
  35516. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35517. use function floor;
  35518. use function sprintf;
  35519. /**
  35520. * @psalm-immutable
  35521. */
  35522. final class Duration
  35523. {
  35524. private readonly float $nanoseconds;
  35525. private readonly int $hours;
  35526. private readonly int $minutes;
  35527. private readonly int $seconds;
  35528. private readonly int $milliseconds;
  35529. public static function fromMicroseconds(float $microseconds): self
  35530. {
  35531. return new self($microseconds * 1000);
  35532. }
  35533. public static function fromNanoseconds(float $nanoseconds): self
  35534. {
  35535. return new self($nanoseconds);
  35536. }
  35537. private function __construct(float $nanoseconds)
  35538. {
  35539. $this->nanoseconds = $nanoseconds;
  35540. $timeInMilliseconds = $nanoseconds / 1000000;
  35541. $hours = floor($timeInMilliseconds / 60 / 60 / 1000);
  35542. $hoursInMilliseconds = $hours * 60 * 60 * 1000;
  35543. $minutes = floor($timeInMilliseconds / 60 / 1000) % 60;
  35544. $minutesInMilliseconds = $minutes * 60 * 1000;
  35545. $seconds = floor(($timeInMilliseconds - $hoursInMilliseconds - $minutesInMilliseconds) / 1000);
  35546. $secondsInMilliseconds = $seconds * 1000;
  35547. $milliseconds = $timeInMilliseconds - $hoursInMilliseconds - $minutesInMilliseconds - $secondsInMilliseconds;
  35548. $this->hours = (int) $hours;
  35549. $this->minutes = $minutes;
  35550. $this->seconds = (int) $seconds;
  35551. $this->milliseconds = (int) $milliseconds;
  35552. }
  35553. public function asNanoseconds(): float
  35554. {
  35555. return $this->nanoseconds;
  35556. }
  35557. public function asMicroseconds(): float
  35558. {
  35559. return $this->nanoseconds / 1000;
  35560. }
  35561. public function asMilliseconds(): float
  35562. {
  35563. return $this->nanoseconds / 1000000;
  35564. }
  35565. public function asSeconds(): float
  35566. {
  35567. return $this->nanoseconds / 1000000000;
  35568. }
  35569. public function asString(): string
  35570. {
  35571. $result = '';
  35572. if ($this->hours > 0) {
  35573. $result = sprintf('%02d', $this->hours) . ':';
  35574. }
  35575. $result .= sprintf('%02d', $this->minutes) . ':';
  35576. $result .= sprintf('%02d', $this->seconds);
  35577. if ($this->milliseconds > 0) {
  35578. $result .= '.' . sprintf('%03d', $this->milliseconds);
  35579. }
  35580. return $result;
  35581. }
  35582. }
  35583. BSD 3-Clause License
  35584. Copyright (c) 2010-2023, Sebastian Bergmann
  35585. All rights reserved.
  35586. Redistribution and use in source and binary forms, with or without
  35587. modification, are permitted provided that the following conditions are met:
  35588. 1. Redistributions of source code must retain the above copyright notice, this
  35589. list of conditions and the following disclaimer.
  35590. 2. Redistributions in binary form must reproduce the above copyright notice,
  35591. this list of conditions and the following disclaimer in the documentation
  35592. and/or other materials provided with the distribution.
  35593. 3. Neither the name of the copyright holder nor the names of its
  35594. contributors may be used to endorse or promote products derived from
  35595. this software without specific prior written permission.
  35596. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  35597. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35598. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35599. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  35600. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35601. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  35602. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35603. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35604. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35605. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35606. <?php
  35607. declare (strict_types=1);
  35608. /*
  35609. * This file is part of phpunit/php-timer.
  35610. *
  35611. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35612. *
  35613. * For the full copyright and license information, please view the LICENSE
  35614. * file that was distributed with this source code.
  35615. */
  35616. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35617. use function is_float;
  35618. use function memory_get_peak_usage;
  35619. use function microtime;
  35620. use function sprintf;
  35621. final class ResourceUsageFormatter
  35622. {
  35623. /**
  35624. * @psalm-var array<string,int>
  35625. */
  35626. private const SIZES = ['GB' => 1073741824, 'MB' => 1048576, 'KB' => 1024];
  35627. public function resourceUsage(Duration $duration): string
  35628. {
  35629. return sprintf('Time: %s, Memory: %s', $duration->asString(), $this->bytesToString(memory_get_peak_usage(\true)));
  35630. }
  35631. /**
  35632. * @throws TimeSinceStartOfRequestNotAvailableException
  35633. */
  35634. public function resourceUsageSinceStartOfRequest(): string
  35635. {
  35636. if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) {
  35637. throw new TimeSinceStartOfRequestNotAvailableException('Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not available');
  35638. }
  35639. if (!is_float($_SERVER['REQUEST_TIME_FLOAT'])) {
  35640. throw new TimeSinceStartOfRequestNotAvailableException('Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not of type float');
  35641. }
  35642. return $this->resourceUsage(Duration::fromMicroseconds(1000000 * (microtime(\true) - $_SERVER['REQUEST_TIME_FLOAT'])));
  35643. }
  35644. private function bytesToString(int $bytes): string
  35645. {
  35646. foreach (self::SIZES as $unit => $value) {
  35647. if ($bytes >= $value) {
  35648. return sprintf('%.2f %s', $bytes / $value, $unit);
  35649. }
  35650. }
  35651. // @codeCoverageIgnoreStart
  35652. return $bytes . ' byte' . ($bytes !== 1 ? 's' : '');
  35653. // @codeCoverageIgnoreEnd
  35654. }
  35655. }
  35656. <?php
  35657. declare (strict_types=1);
  35658. /*
  35659. * This file is part of phpunit/php-timer.
  35660. *
  35661. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35662. *
  35663. * For the full copyright and license information, please view the LICENSE
  35664. * file that was distributed with this source code.
  35665. */
  35666. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35667. use function array_pop;
  35668. use function hrtime;
  35669. final class Timer
  35670. {
  35671. /**
  35672. * @psalm-var list<float>
  35673. */
  35674. private array $startTimes = [];
  35675. public function start(): void
  35676. {
  35677. $this->startTimes[] = (float) hrtime(\true);
  35678. }
  35679. /**
  35680. * @throws NoActiveTimerException
  35681. */
  35682. public function stop(): Duration
  35683. {
  35684. if (empty($this->startTimes)) {
  35685. throw new NoActiveTimerException('Timer::start() has to be called before Timer::stop()');
  35686. }
  35687. return Duration::fromNanoseconds((float) hrtime(\true) - array_pop($this->startTimes));
  35688. }
  35689. }
  35690. <?php
  35691. declare (strict_types=1);
  35692. /*
  35693. * This file is part of phpunit/php-timer.
  35694. *
  35695. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35696. *
  35697. * For the full copyright and license information, please view the LICENSE
  35698. * file that was distributed with this source code.
  35699. */
  35700. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35701. use Throwable;
  35702. interface Exception extends Throwable
  35703. {
  35704. }
  35705. <?php
  35706. declare (strict_types=1);
  35707. /*
  35708. * This file is part of phpunit/php-timer.
  35709. *
  35710. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35711. *
  35712. * For the full copyright and license information, please view the LICENSE
  35713. * file that was distributed with this source code.
  35714. */
  35715. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35716. use LogicException;
  35717. final class NoActiveTimerException extends LogicException implements Exception
  35718. {
  35719. }
  35720. <?php
  35721. declare (strict_types=1);
  35722. /*
  35723. * This file is part of phpunit/php-timer.
  35724. *
  35725. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35726. *
  35727. * For the full copyright and license information, please view the LICENSE
  35728. * file that was distributed with this source code.
  35729. */
  35730. namespace PHPUnitPHAR\SebastianBergmann\Timer;
  35731. use RuntimeException;
  35732. final class TimeSinceStartOfRequestNotAvailableException extends RuntimeException implements Exception
  35733. {
  35734. }
  35735. <?xml version="1.0" encoding="UTF-8"?>
  35736. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  35737. <xs:annotation>
  35738. <xs:documentation source="https://phpunit.de/documentation.html">
  35739. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.5 may be structured.
  35740. </xs:documentation>
  35741. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  35742. </xs:annotation>
  35743. <xs:element name="phpunit" type="phpUnitType">
  35744. <xs:annotation>
  35745. <xs:documentation>Root Element</xs:documentation>
  35746. </xs:annotation>
  35747. </xs:element>
  35748. <xs:complexType name="sourceType">
  35749. <xs:all>
  35750. <xs:element name="include" minOccurs="0" maxOccurs="1">
  35751. <xs:complexType>
  35752. <xs:group ref="sourcePathGroup"/>
  35753. </xs:complexType>
  35754. </xs:element>
  35755. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  35756. <xs:complexType>
  35757. <xs:group ref="sourcePathGroup"/>
  35758. </xs:complexType>
  35759. </xs:element>
  35760. </xs:all>
  35761. <xs:attribute name="baseline" type="xs:anyURI"/>
  35762. <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
  35763. <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
  35764. <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
  35765. <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
  35766. <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
  35767. <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
  35768. <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
  35769. <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
  35770. <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
  35771. <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
  35772. </xs:complexType>
  35773. <xs:group name="sourcePathGroup">
  35774. <xs:sequence>
  35775. <xs:choice minOccurs="0" maxOccurs="unbounded">
  35776. <xs:element name="directory" type="sourceDirectoryType"/>
  35777. <xs:element name="file" type="xs:anyURI"/>
  35778. </xs:choice>
  35779. </xs:sequence>
  35780. </xs:group>
  35781. <xs:complexType name="sourceDirectoryType">
  35782. <xs:simpleContent>
  35783. <xs:extension base="xs:string">
  35784. <xs:attribute type="xs:string" name="prefix" default=""/>
  35785. <xs:attribute type="xs:string" name="suffix" default=".php"/>
  35786. </xs:extension>
  35787. </xs:simpleContent>
  35788. </xs:complexType>
  35789. <xs:complexType name="coverageType">
  35790. <xs:all>
  35791. <xs:element name="report" minOccurs="0" maxOccurs="1">
  35792. <xs:complexType>
  35793. <xs:group ref="coverageReportGroup"/>
  35794. </xs:complexType>
  35795. </xs:element>
  35796. </xs:all>
  35797. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  35798. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  35799. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  35800. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  35801. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  35802. </xs:complexType>
  35803. <xs:complexType name="loggingType">
  35804. <xs:group ref="loggingGroup"/>
  35805. </xs:complexType>
  35806. <xs:complexType name="groupsType">
  35807. <xs:choice>
  35808. <xs:sequence>
  35809. <xs:element name="include" type="groupType"/>
  35810. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  35811. </xs:sequence>
  35812. <xs:sequence>
  35813. <xs:element name="exclude" type="groupType"/>
  35814. </xs:sequence>
  35815. </xs:choice>
  35816. </xs:complexType>
  35817. <xs:complexType name="groupType">
  35818. <xs:sequence>
  35819. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  35820. </xs:sequence>
  35821. </xs:complexType>
  35822. <xs:complexType name="extensionsType">
  35823. <xs:sequence>
  35824. <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
  35825. </xs:sequence>
  35826. </xs:complexType>
  35827. <xs:complexType name="bootstrapType">
  35828. <xs:sequence>
  35829. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  35830. </xs:sequence>
  35831. <xs:attribute name="class" type="xs:string" use="required"/>
  35832. </xs:complexType>
  35833. <xs:complexType name="parameterType">
  35834. <xs:attribute name="name" type="xs:string" use="required"/>
  35835. <xs:attribute name="value" type="xs:string" use="required"/>
  35836. </xs:complexType>
  35837. <xs:simpleType name="columnsType">
  35838. <xs:union>
  35839. <xs:simpleType>
  35840. <xs:restriction base="xs:integer"/>
  35841. </xs:simpleType>
  35842. <xs:simpleType>
  35843. <xs:restriction base="xs:string">
  35844. <xs:enumeration value="max"/>
  35845. </xs:restriction>
  35846. </xs:simpleType>
  35847. </xs:union>
  35848. </xs:simpleType>
  35849. <xs:simpleType name="executionOrderType">
  35850. <xs:restriction base="xs:string">
  35851. <xs:enumeration value="default"/>
  35852. <xs:enumeration value="defects"/>
  35853. <xs:enumeration value="depends"/>
  35854. <xs:enumeration value="depends,defects"/>
  35855. <xs:enumeration value="depends,duration"/>
  35856. <xs:enumeration value="depends,random"/>
  35857. <xs:enumeration value="depends,reverse"/>
  35858. <xs:enumeration value="depends,size"/>
  35859. <xs:enumeration value="duration"/>
  35860. <xs:enumeration value="no-depends"/>
  35861. <xs:enumeration value="no-depends,defects"/>
  35862. <xs:enumeration value="no-depends,duration"/>
  35863. <xs:enumeration value="no-depends,random"/>
  35864. <xs:enumeration value="no-depends,reverse"/>
  35865. <xs:enumeration value="no-depends,size"/>
  35866. <xs:enumeration value="random"/>
  35867. <xs:enumeration value="reverse"/>
  35868. <xs:enumeration value="size"/>
  35869. </xs:restriction>
  35870. </xs:simpleType>
  35871. <xs:complexType name="phpType">
  35872. <xs:sequence>
  35873. <xs:choice maxOccurs="unbounded">
  35874. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  35875. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35876. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35877. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35878. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35879. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35880. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35881. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35882. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35883. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35884. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  35885. </xs:choice>
  35886. </xs:sequence>
  35887. </xs:complexType>
  35888. <xs:complexType name="namedValueType">
  35889. <xs:attribute name="name" use="required" type="xs:string"/>
  35890. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  35891. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  35892. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  35893. </xs:complexType>
  35894. <xs:complexType name="phpUnitType">
  35895. <xs:annotation>
  35896. <xs:documentation>The main type specifying the document structure</xs:documentation>
  35897. </xs:annotation>
  35898. <xs:group ref="configGroup"/>
  35899. <xs:attributeGroup ref="configAttributeGroup"/>
  35900. </xs:complexType>
  35901. <xs:attributeGroup name="configAttributeGroup">
  35902. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  35903. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  35904. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  35905. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  35906. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  35907. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  35908. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  35909. <xs:attribute name="columns" type="columnsType" default="80"/>
  35910. <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
  35911. <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
  35912. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  35913. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  35914. <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
  35915. <xs:attribute name="failOnPhpunitDeprecation" type="xs:boolean" default="false"/>
  35916. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  35917. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  35918. <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
  35919. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  35920. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  35921. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  35922. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  35923. <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
  35924. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  35925. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  35926. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  35927. <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
  35928. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  35929. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  35930. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  35931. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  35932. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  35933. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  35934. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  35935. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  35936. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  35937. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  35938. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  35939. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  35940. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  35941. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  35942. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  35943. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  35944. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  35945. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  35946. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  35947. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  35948. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  35949. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  35950. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  35951. <xs:attribute name="displayDetailsOnPhpunitDeprecations" type="xs:boolean" default="false"/>
  35952. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  35953. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  35954. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  35955. </xs:attributeGroup>
  35956. <xs:group name="configGroup">
  35957. <xs:all>
  35958. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  35959. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  35960. <xs:element name="source" type="sourceType" minOccurs="0"/>
  35961. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  35962. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  35963. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  35964. <xs:element name="php" type="phpType" minOccurs="0"/>
  35965. </xs:all>
  35966. </xs:group>
  35967. <xs:element name="testSuiteFacet" abstract="true"/>
  35968. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  35969. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  35970. <xs:complexType name="testSuitesType">
  35971. <xs:sequence>
  35972. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  35973. </xs:sequence>
  35974. </xs:complexType>
  35975. <xs:complexType name="testSuiteType">
  35976. <xs:sequence>
  35977. <xs:choice minOccurs="0" maxOccurs="unbounded">
  35978. <xs:group ref="testSuitePathGroup"/>
  35979. <xs:element name="exclude" type="xs:string"/>
  35980. </xs:choice>
  35981. </xs:sequence>
  35982. <xs:attribute name="name" type="xs:string" use="required"/>
  35983. </xs:complexType>
  35984. <xs:group name="testSuitePathGroup">
  35985. <xs:sequence>
  35986. <xs:choice minOccurs="0" maxOccurs="unbounded">
  35987. <xs:element name="directory" type="testSuiteDirectoryType"/>
  35988. <xs:element name="file" type="testSuiteFileType"/>
  35989. </xs:choice>
  35990. </xs:sequence>
  35991. </xs:group>
  35992. <xs:complexType name="testSuiteDirectoryType">
  35993. <xs:simpleContent>
  35994. <xs:extension base="xs:string">
  35995. <xs:attribute type="xs:string" name="prefix" default=""/>
  35996. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  35997. <xs:attributeGroup ref="phpVersionGroup"/>
  35998. </xs:extension>
  35999. </xs:simpleContent>
  36000. </xs:complexType>
  36001. <xs:complexType name="testSuiteFileType">
  36002. <xs:simpleContent>
  36003. <xs:extension base="xs:anyURI">
  36004. <xs:attributeGroup ref="phpVersionGroup"/>
  36005. </xs:extension>
  36006. </xs:simpleContent>
  36007. </xs:complexType>
  36008. <xs:attributeGroup name="phpVersionGroup">
  36009. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  36010. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  36011. </xs:attributeGroup>
  36012. <xs:group name="coverageReportGroup">
  36013. <xs:all>
  36014. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  36015. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  36016. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  36017. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  36018. <xs:element name="php" type="logToFileType" minOccurs="0" />
  36019. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  36020. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  36021. </xs:all>
  36022. </xs:group>
  36023. <xs:group name="loggingGroup">
  36024. <xs:all>
  36025. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  36026. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  36027. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  36028. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  36029. </xs:all>
  36030. </xs:group>
  36031. <xs:complexType name="logToFileType">
  36032. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  36033. </xs:complexType>
  36034. <xs:complexType name="logToDirectoryType">
  36035. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  36036. </xs:complexType>
  36037. <xs:complexType name="coverageReportCrap4JType">
  36038. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  36039. <xs:attribute name="threshold" type="xs:integer"/>
  36040. </xs:complexType>
  36041. <xs:complexType name="coverageReportHtmlType">
  36042. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  36043. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  36044. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  36045. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  36046. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  36047. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  36048. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  36049. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  36050. <xs:attribute name="customCssFile" type="xs:string"/>
  36051. </xs:complexType>
  36052. <xs:complexType name="coverageReportTextType">
  36053. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  36054. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  36055. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  36056. </xs:complexType>
  36057. </xs:schema>
  36058. <?php
  36059. declare (strict_types=1);
  36060. /*
  36061. * This file is part of PHPUnit.
  36062. *
  36063. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36064. *
  36065. * For the full copyright and license information, please view the LICENSE
  36066. * file that was distributed with this source code.
  36067. */
  36068. namespace PHPUnit\Event;
  36069. /**
  36070. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36071. *
  36072. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  36073. */
  36074. final class CollectingDispatcher implements \PHPUnit\Event\Dispatcher
  36075. {
  36076. private \PHPUnit\Event\EventCollection $events;
  36077. public function __construct()
  36078. {
  36079. $this->events = new \PHPUnit\Event\EventCollection();
  36080. }
  36081. public function dispatch(\PHPUnit\Event\Event $event): void
  36082. {
  36083. $this->events->add($event);
  36084. }
  36085. public function flush(): \PHPUnit\Event\EventCollection
  36086. {
  36087. $events = $this->events;
  36088. $this->events = new \PHPUnit\Event\EventCollection();
  36089. return $events;
  36090. }
  36091. }
  36092. <?php
  36093. declare (strict_types=1);
  36094. /*
  36095. * This file is part of PHPUnit.
  36096. *
  36097. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36098. *
  36099. * For the full copyright and license information, please view the LICENSE
  36100. * file that was distributed with this source code.
  36101. */
  36102. namespace PHPUnit\Event;
  36103. /**
  36104. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36105. *
  36106. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  36107. */
  36108. final class DeferringDispatcher implements \PHPUnit\Event\SubscribableDispatcher
  36109. {
  36110. private readonly \PHPUnit\Event\SubscribableDispatcher $dispatcher;
  36111. private \PHPUnit\Event\EventCollection $events;
  36112. private bool $recording = \true;
  36113. public function __construct(\PHPUnit\Event\SubscribableDispatcher $dispatcher)
  36114. {
  36115. $this->dispatcher = $dispatcher;
  36116. $this->events = new \PHPUnit\Event\EventCollection();
  36117. }
  36118. public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
  36119. {
  36120. $this->dispatcher->registerTracer($tracer);
  36121. }
  36122. public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
  36123. {
  36124. $this->dispatcher->registerSubscriber($subscriber);
  36125. }
  36126. public function dispatch(\PHPUnit\Event\Event $event): void
  36127. {
  36128. if ($this->recording) {
  36129. $this->events->add($event);
  36130. return;
  36131. }
  36132. $this->dispatcher->dispatch($event);
  36133. }
  36134. public function flush(): void
  36135. {
  36136. $this->recording = \false;
  36137. foreach ($this->events as $event) {
  36138. $this->dispatcher->dispatch($event);
  36139. }
  36140. $this->events = new \PHPUnit\Event\EventCollection();
  36141. }
  36142. }
  36143. <?php
  36144. declare (strict_types=1);
  36145. /*
  36146. * This file is part of PHPUnit.
  36147. *
  36148. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36149. *
  36150. * For the full copyright and license information, please view the LICENSE
  36151. * file that was distributed with this source code.
  36152. */
  36153. namespace PHPUnit\Event;
  36154. use const PHP_EOL;
  36155. use function array_key_exists;
  36156. use function dirname;
  36157. use function sprintf;
  36158. use function str_starts_with;
  36159. use Throwable;
  36160. /**
  36161. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36162. *
  36163. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  36164. */
  36165. final class DirectDispatcher implements \PHPUnit\Event\SubscribableDispatcher
  36166. {
  36167. private readonly \PHPUnit\Event\TypeMap $typeMap;
  36168. /**
  36169. * @psalm-var array<class-string, list<Subscriber>>
  36170. */
  36171. private array $subscribers = [];
  36172. /**
  36173. * @psalm-var list<Tracer\Tracer>
  36174. */
  36175. private array $tracers = [];
  36176. public function __construct(\PHPUnit\Event\TypeMap $map)
  36177. {
  36178. $this->typeMap = $map;
  36179. }
  36180. public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
  36181. {
  36182. $this->tracers[] = $tracer;
  36183. }
  36184. /**
  36185. * @throws MapError
  36186. * @throws UnknownSubscriberTypeException
  36187. */
  36188. public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
  36189. {
  36190. if (!$this->typeMap->isKnownSubscriberType($subscriber)) {
  36191. throw new \PHPUnit\Event\UnknownSubscriberTypeException(sprintf('Subscriber "%s" does not implement any known interface - did you forget to register it?', $subscriber::class));
  36192. }
  36193. $eventClassName = $this->typeMap->map($subscriber);
  36194. if (!array_key_exists($eventClassName, $this->subscribers)) {
  36195. $this->subscribers[$eventClassName] = [];
  36196. }
  36197. $this->subscribers[$eventClassName][] = $subscriber;
  36198. }
  36199. /**
  36200. * @throws Throwable
  36201. * @throws UnknownEventTypeException
  36202. */
  36203. public function dispatch(\PHPUnit\Event\Event $event): void
  36204. {
  36205. $eventClassName = $event::class;
  36206. if (!$this->typeMap->isKnownEventType($event)) {
  36207. throw new \PHPUnit\Event\UnknownEventTypeException(sprintf('Unknown event type "%s"', $eventClassName));
  36208. }
  36209. foreach ($this->tracers as $tracer) {
  36210. try {
  36211. $tracer->trace($event);
  36212. // @codeCoverageIgnoreStart
  36213. } catch (Throwable $t) {
  36214. $this->handleThrowable($t);
  36215. }
  36216. // @codeCoverageIgnoreEnd
  36217. }
  36218. if (!array_key_exists($eventClassName, $this->subscribers)) {
  36219. return;
  36220. }
  36221. foreach ($this->subscribers[$eventClassName] as $subscriber) {
  36222. try {
  36223. $subscriber->notify($event);
  36224. } catch (Throwable $t) {
  36225. $this->handleThrowable($t);
  36226. }
  36227. }
  36228. }
  36229. /**
  36230. * @throws Throwable
  36231. */
  36232. public function handleThrowable(Throwable $t): void
  36233. {
  36234. if ($this->isThrowableFromThirdPartySubscriber($t)) {
  36235. \PHPUnit\Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Exception in third-party event subscriber: %s%s%s', $t->getMessage(), PHP_EOL, $t->getTraceAsString()));
  36236. return;
  36237. }
  36238. // @codeCoverageIgnoreStart
  36239. throw $t;
  36240. // @codeCoverageIgnoreEnd
  36241. }
  36242. private function isThrowableFromThirdPartySubscriber(Throwable $t): bool
  36243. {
  36244. return !str_starts_with($t->getFile(), dirname(__DIR__, 2));
  36245. }
  36246. }
  36247. <?php
  36248. declare (strict_types=1);
  36249. /*
  36250. * This file is part of PHPUnit.
  36251. *
  36252. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36253. *
  36254. * For the full copyright and license information, please view the LICENSE
  36255. * file that was distributed with this source code.
  36256. */
  36257. namespace PHPUnit\Event;
  36258. /**
  36259. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36260. *
  36261. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  36262. */
  36263. interface Dispatcher
  36264. {
  36265. /**
  36266. * @throws UnknownEventTypeException
  36267. */
  36268. public function dispatch(\PHPUnit\Event\Event $event): void;
  36269. }
  36270. <?php
  36271. declare (strict_types=1);
  36272. /*
  36273. * This file is part of PHPUnit.
  36274. *
  36275. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36276. *
  36277. * For the full copyright and license information, please view the LICENSE
  36278. * file that was distributed with this source code.
  36279. */
  36280. namespace PHPUnit\Event;
  36281. /**
  36282. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36283. *
  36284. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  36285. */
  36286. interface SubscribableDispatcher extends \PHPUnit\Event\Dispatcher
  36287. {
  36288. /**
  36289. * @throws UnknownSubscriberTypeException
  36290. */
  36291. public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void;
  36292. public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void;
  36293. }
  36294. <?php
  36295. declare (strict_types=1);
  36296. /*
  36297. * This file is part of PHPUnit.
  36298. *
  36299. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36300. *
  36301. * For the full copyright and license information, please view the LICENSE
  36302. * file that was distributed with this source code.
  36303. */
  36304. namespace PHPUnit\Event;
  36305. use PHPUnit\Event\Code\ClassMethod;
  36306. use PHPUnit\Event\Code\ComparisonFailure;
  36307. use PHPUnit\Event\Code\Throwable;
  36308. use PHPUnit\Event\Test\DataProviderMethodCalled;
  36309. use PHPUnit\Event\Test\DataProviderMethodFinished;
  36310. use PHPUnit\Event\TestSuite\Filtered as TestSuiteFiltered;
  36311. use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
  36312. use PHPUnit\Event\TestSuite\Loaded as TestSuiteLoaded;
  36313. use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
  36314. use PHPUnit\Event\TestSuite\Sorted as TestSuiteSorted;
  36315. use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
  36316. use PHPUnit\Event\TestSuite\TestSuite;
  36317. use PHPUnit\Framework\Constraint;
  36318. use PHPUnit\TextUI\Configuration\Configuration;
  36319. use PHPUnit\Util\Exporter;
  36320. /**
  36321. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  36322. *
  36323. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  36324. */
  36325. final class DispatchingEmitter implements \PHPUnit\Event\Emitter
  36326. {
  36327. private readonly \PHPUnit\Event\Dispatcher $dispatcher;
  36328. private readonly \PHPUnit\Event\Telemetry\System $system;
  36329. private readonly \PHPUnit\Event\Telemetry\Snapshot $startSnapshot;
  36330. private \PHPUnit\Event\Telemetry\Snapshot $previousSnapshot;
  36331. private bool $exportObjects = \false;
  36332. public function __construct(\PHPUnit\Event\Dispatcher $dispatcher, \PHPUnit\Event\Telemetry\System $system)
  36333. {
  36334. $this->dispatcher = $dispatcher;
  36335. $this->system = $system;
  36336. $this->startSnapshot = $system->snapshot();
  36337. $this->previousSnapshot = $this->startSnapshot;
  36338. }
  36339. /**
  36340. * @deprecated
  36341. */
  36342. public function exportObjects(): void
  36343. {
  36344. $this->exportObjects = \true;
  36345. }
  36346. /**
  36347. * @deprecated
  36348. */
  36349. public function exportsObjects(): bool
  36350. {
  36351. return $this->exportObjects;
  36352. }
  36353. /**
  36354. * @throws InvalidArgumentException
  36355. * @throws UnknownEventTypeException
  36356. */
  36357. public function applicationStarted(): void
  36358. {
  36359. $this->dispatcher->dispatch(new \PHPUnit\Event\Application\Started($this->telemetryInfo(), new \PHPUnit\Event\Runtime\Runtime()));
  36360. }
  36361. /**
  36362. * @throws InvalidArgumentException
  36363. * @throws UnknownEventTypeException
  36364. */
  36365. public function testRunnerStarted(): void
  36366. {
  36367. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Started($this->telemetryInfo()));
  36368. }
  36369. /**
  36370. * @throws InvalidArgumentException
  36371. * @throws UnknownEventTypeException
  36372. */
  36373. public function testRunnerConfigured(Configuration $configuration): void
  36374. {
  36375. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Configured($this->telemetryInfo(), $configuration));
  36376. }
  36377. /**
  36378. * @throws InvalidArgumentException
  36379. * @throws UnknownEventTypeException
  36380. */
  36381. public function testRunnerBootstrapFinished(string $filename): void
  36382. {
  36383. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\BootstrapFinished($this->telemetryInfo(), $filename));
  36384. }
  36385. /**
  36386. * @throws InvalidArgumentException
  36387. * @throws UnknownEventTypeException
  36388. */
  36389. public function testRunnerLoadedExtensionFromPhar(string $filename, string $name, string $version): void
  36390. {
  36391. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar($this->telemetryInfo(), $filename, $name, $version));
  36392. }
  36393. /**
  36394. * @psalm-param class-string $className
  36395. * @psalm-param array<string, string> $parameters
  36396. *
  36397. * @throws InvalidArgumentException
  36398. * @throws UnknownEventTypeException
  36399. */
  36400. public function testRunnerBootstrappedExtension(string $className, array $parameters): void
  36401. {
  36402. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExtensionBootstrapped($this->telemetryInfo(), $className, $parameters));
  36403. }
  36404. /**
  36405. * @throws InvalidArgumentException
  36406. * @throws UnknownEventTypeException
  36407. */
  36408. public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod): void
  36409. {
  36410. $this->dispatcher->dispatch(new DataProviderMethodCalled($this->telemetryInfo(), $testMethod, $dataProviderMethod));
  36411. }
  36412. /**
  36413. * @throws InvalidArgumentException
  36414. * @throws UnknownEventTypeException
  36415. */
  36416. public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods): void
  36417. {
  36418. $this->dispatcher->dispatch(new DataProviderMethodFinished($this->telemetryInfo(), $testMethod, ...$calledMethods));
  36419. }
  36420. /**
  36421. * @throws InvalidArgumentException
  36422. * @throws UnknownEventTypeException
  36423. */
  36424. public function testSuiteLoaded(TestSuite $testSuite): void
  36425. {
  36426. $this->dispatcher->dispatch(new TestSuiteLoaded($this->telemetryInfo(), $testSuite));
  36427. }
  36428. /**
  36429. * @throws InvalidArgumentException
  36430. * @throws UnknownEventTypeException
  36431. */
  36432. public function testSuiteFiltered(TestSuite $testSuite): void
  36433. {
  36434. $this->dispatcher->dispatch(new TestSuiteFiltered($this->telemetryInfo(), $testSuite));
  36435. }
  36436. /**
  36437. * @throws InvalidArgumentException
  36438. * @throws UnknownEventTypeException
  36439. */
  36440. public function testSuiteSorted(int $executionOrder, int $executionOrderDefects, bool $resolveDependencies): void
  36441. {
  36442. $this->dispatcher->dispatch(new TestSuiteSorted($this->telemetryInfo(), $executionOrder, $executionOrderDefects, $resolveDependencies));
  36443. }
  36444. /**
  36445. * @throws InvalidArgumentException
  36446. * @throws UnknownEventTypeException
  36447. */
  36448. public function testRunnerEventFacadeSealed(): void
  36449. {
  36450. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\EventFacadeSealed($this->telemetryInfo()));
  36451. }
  36452. /**
  36453. * @throws InvalidArgumentException
  36454. * @throws UnknownEventTypeException
  36455. */
  36456. public function testRunnerExecutionStarted(TestSuite $testSuite): void
  36457. {
  36458. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionStarted($this->telemetryInfo(), $testSuite));
  36459. }
  36460. /**
  36461. * @throws InvalidArgumentException
  36462. * @throws UnknownEventTypeException
  36463. */
  36464. public function testRunnerDisabledGarbageCollection(): void
  36465. {
  36466. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionDisabled($this->telemetryInfo()));
  36467. }
  36468. /**
  36469. * @throws InvalidArgumentException
  36470. * @throws UnknownEventTypeException
  36471. */
  36472. public function testRunnerTriggeredGarbageCollection(): void
  36473. {
  36474. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionTriggered($this->telemetryInfo()));
  36475. }
  36476. /**
  36477. * @throws InvalidArgumentException
  36478. * @throws UnknownEventTypeException
  36479. */
  36480. public function testSuiteSkipped(TestSuite $testSuite, string $message): void
  36481. {
  36482. $this->dispatcher->dispatch(new TestSuiteSkipped($this->telemetryInfo(), $testSuite, $message));
  36483. }
  36484. /**
  36485. * @throws InvalidArgumentException
  36486. * @throws UnknownEventTypeException
  36487. */
  36488. public function testSuiteStarted(TestSuite $testSuite): void
  36489. {
  36490. $this->dispatcher->dispatch(new TestSuiteStarted($this->telemetryInfo(), $testSuite));
  36491. }
  36492. /**
  36493. * @throws InvalidArgumentException
  36494. * @throws UnknownEventTypeException
  36495. */
  36496. public function testPreparationStarted(\PHPUnit\Event\Code\Test $test): void
  36497. {
  36498. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationStarted($this->telemetryInfo(), $test));
  36499. }
  36500. /**
  36501. * @throws InvalidArgumentException
  36502. * @throws UnknownEventTypeException
  36503. */
  36504. public function testPreparationFailed(\PHPUnit\Event\Code\Test $test): void
  36505. {
  36506. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationFailed($this->telemetryInfo(), $test));
  36507. }
  36508. /**
  36509. * @psalm-param class-string $testClassName
  36510. *
  36511. * @throws InvalidArgumentException
  36512. * @throws UnknownEventTypeException
  36513. */
  36514. public function testBeforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
  36515. {
  36516. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36517. }
  36518. /**
  36519. * @psalm-param class-string $testClassName
  36520. *
  36521. * @throws InvalidArgumentException
  36522. * @throws UnknownEventTypeException
  36523. */
  36524. public function testBeforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
  36525. {
  36526. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
  36527. }
  36528. /**
  36529. * @psalm-param class-string $testClassName
  36530. *
  36531. * @throws InvalidArgumentException
  36532. * @throws UnknownEventTypeException
  36533. */
  36534. public function testBeforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36535. {
  36536. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36537. }
  36538. /**
  36539. * @psalm-param class-string $testClassName
  36540. *
  36541. * @throws InvalidArgumentException
  36542. * @throws UnknownEventTypeException
  36543. */
  36544. public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
  36545. {
  36546. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36547. }
  36548. /**
  36549. * @psalm-param class-string $testClassName
  36550. *
  36551. * @throws InvalidArgumentException
  36552. * @throws UnknownEventTypeException
  36553. */
  36554. public function testBeforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36555. {
  36556. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36557. }
  36558. /**
  36559. * @psalm-param class-string $testClassName
  36560. *
  36561. * @throws InvalidArgumentException
  36562. * @throws UnknownEventTypeException
  36563. */
  36564. public function testPreConditionCalled(string $testClassName, ClassMethod $calledMethod): void
  36565. {
  36566. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36567. }
  36568. /**
  36569. * @psalm-param class-string $testClassName
  36570. *
  36571. * @throws InvalidArgumentException
  36572. * @throws UnknownEventTypeException
  36573. */
  36574. public function testPreConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36575. {
  36576. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36577. }
  36578. /**
  36579. * @throws InvalidArgumentException
  36580. * @throws UnknownEventTypeException
  36581. */
  36582. public function testPrepared(\PHPUnit\Event\Code\Test $test): void
  36583. {
  36584. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Prepared($this->telemetryInfo(), $test));
  36585. }
  36586. /**
  36587. * @psalm-param class-string $className
  36588. *
  36589. * @throws InvalidArgumentException
  36590. * @throws UnknownEventTypeException
  36591. */
  36592. public function testRegisteredComparator(string $className): void
  36593. {
  36594. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ComparatorRegistered($this->telemetryInfo(), $className));
  36595. }
  36596. /**
  36597. * @throws InvalidArgumentException
  36598. * @throws UnknownEventTypeException
  36599. *
  36600. * @deprecated
  36601. */
  36602. public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message): void
  36603. {
  36604. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionSucceeded($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message));
  36605. }
  36606. /**
  36607. * @throws InvalidArgumentException
  36608. * @throws UnknownEventTypeException
  36609. *
  36610. * @deprecated
  36611. */
  36612. public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message): void
  36613. {
  36614. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionFailed($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message));
  36615. }
  36616. /**
  36617. * @psalm-param class-string $className
  36618. *
  36619. * @throws InvalidArgumentException
  36620. * @throws UnknownEventTypeException
  36621. */
  36622. public function testCreatedMockObject(string $className): void
  36623. {
  36624. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectCreated($this->telemetryInfo(), $className));
  36625. }
  36626. /**
  36627. * @psalm-param list<class-string> $interfaces
  36628. *
  36629. * @throws InvalidArgumentException
  36630. * @throws UnknownEventTypeException
  36631. */
  36632. public function testCreatedMockObjectForIntersectionOfInterfaces(array $interfaces): void
  36633. {
  36634. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated($this->telemetryInfo(), $interfaces));
  36635. }
  36636. /**
  36637. * @psalm-param trait-string $traitName
  36638. *
  36639. * @throws InvalidArgumentException
  36640. * @throws UnknownEventTypeException
  36641. */
  36642. public function testCreatedMockObjectForTrait(string $traitName): void
  36643. {
  36644. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForTraitCreated($this->telemetryInfo(), $traitName));
  36645. }
  36646. /**
  36647. * @psalm-param class-string $className
  36648. *
  36649. * @throws InvalidArgumentException
  36650. * @throws UnknownEventTypeException
  36651. */
  36652. public function testCreatedMockObjectForAbstractClass(string $className): void
  36653. {
  36654. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForAbstractClassCreated($this->telemetryInfo(), $className));
  36655. }
  36656. /**
  36657. * @psalm-param class-string $originalClassName
  36658. * @psalm-param class-string $mockClassName
  36659. *
  36660. * @throws InvalidArgumentException
  36661. * @throws UnknownEventTypeException
  36662. */
  36663. public function testCreatedMockObjectFromWsdl(string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options): void
  36664. {
  36665. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectFromWsdlCreated($this->telemetryInfo(), $wsdlFile, $originalClassName, $mockClassName, $methods, $callOriginalConstructor, $options));
  36666. }
  36667. /**
  36668. * @psalm-param class-string $className
  36669. *
  36670. * @throws InvalidArgumentException
  36671. * @throws UnknownEventTypeException
  36672. */
  36673. public function testCreatedPartialMockObject(string $className, string ...$methodNames): void
  36674. {
  36675. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PartialMockObjectCreated($this->telemetryInfo(), $className, ...$methodNames));
  36676. }
  36677. /**
  36678. * @psalm-param class-string $className
  36679. *
  36680. * @throws InvalidArgumentException
  36681. * @throws UnknownEventTypeException
  36682. */
  36683. public function testCreatedTestProxy(string $className, array $constructorArguments): void
  36684. {
  36685. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestProxyCreated($this->telemetryInfo(), $className, Exporter::export($constructorArguments, $this->exportObjects)));
  36686. }
  36687. /**
  36688. * @psalm-param class-string $className
  36689. *
  36690. * @throws InvalidArgumentException
  36691. * @throws UnknownEventTypeException
  36692. */
  36693. public function testCreatedStub(string $className): void
  36694. {
  36695. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestStubCreated($this->telemetryInfo(), $className));
  36696. }
  36697. /**
  36698. * @psalm-param list<class-string> $interfaces
  36699. *
  36700. * @throws InvalidArgumentException
  36701. * @throws UnknownEventTypeException
  36702. */
  36703. public function testCreatedStubForIntersectionOfInterfaces(array $interfaces): void
  36704. {
  36705. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated($this->telemetryInfo(), $interfaces));
  36706. }
  36707. /**
  36708. * @throws InvalidArgumentException
  36709. * @throws UnknownEventTypeException
  36710. */
  36711. public function testErrored(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void
  36712. {
  36713. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Errored($this->telemetryInfo(), $test, $throwable));
  36714. }
  36715. /**
  36716. * @throws InvalidArgumentException
  36717. * @throws UnknownEventTypeException
  36718. */
  36719. public function testFailed(\PHPUnit\Event\Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure): void
  36720. {
  36721. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Failed($this->telemetryInfo(), $test, $throwable, $comparisonFailure));
  36722. }
  36723. /**
  36724. * @throws InvalidArgumentException
  36725. * @throws UnknownEventTypeException
  36726. */
  36727. public function testPassed(\PHPUnit\Event\Code\Test $test): void
  36728. {
  36729. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Passed($this->telemetryInfo(), $test));
  36730. }
  36731. /**
  36732. * @throws InvalidArgumentException
  36733. * @throws UnknownEventTypeException
  36734. */
  36735. public function testConsideredRisky(\PHPUnit\Event\Code\Test $test, string $message): void
  36736. {
  36737. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ConsideredRisky($this->telemetryInfo(), $test, $message));
  36738. }
  36739. /**
  36740. * @throws InvalidArgumentException
  36741. * @throws UnknownEventTypeException
  36742. */
  36743. public function testMarkedAsIncomplete(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void
  36744. {
  36745. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MarkedIncomplete($this->telemetryInfo(), $test, $throwable));
  36746. }
  36747. /**
  36748. * @throws InvalidArgumentException
  36749. * @throws UnknownEventTypeException
  36750. */
  36751. public function testSkipped(\PHPUnit\Event\Code\Test $test, string $message): void
  36752. {
  36753. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Skipped($this->telemetryInfo(), $test, $message));
  36754. }
  36755. /**
  36756. * @psalm-param non-empty-string $message
  36757. *
  36758. * @throws InvalidArgumentException
  36759. * @throws UnknownEventTypeException
  36760. */
  36761. public function testTriggeredPhpunitDeprecation(\PHPUnit\Event\Code\Test $test, string $message): void
  36762. {
  36763. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitDeprecationTriggered($this->telemetryInfo(), $test, $message));
  36764. }
  36765. /**
  36766. * @psalm-param non-empty-string $message
  36767. * @psalm-param non-empty-string $file
  36768. * @psalm-param positive-int $line
  36769. *
  36770. * @throws InvalidArgumentException
  36771. * @throws UnknownEventTypeException
  36772. */
  36773. public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void
  36774. {
  36775. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpDeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest));
  36776. }
  36777. /**
  36778. * @psalm-param non-empty-string $message
  36779. * @psalm-param non-empty-string $file
  36780. * @psalm-param positive-int $line
  36781. *
  36782. * @throws InvalidArgumentException
  36783. * @throws UnknownEventTypeException
  36784. */
  36785. public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void
  36786. {
  36787. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\DeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest));
  36788. }
  36789. /**
  36790. * @psalm-param non-empty-string $message
  36791. * @psalm-param non-empty-string $file
  36792. * @psalm-param positive-int $line
  36793. *
  36794. * @throws InvalidArgumentException
  36795. * @throws UnknownEventTypeException
  36796. */
  36797. public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed): void
  36798. {
  36799. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ErrorTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed));
  36800. }
  36801. /**
  36802. * @psalm-param non-empty-string $message
  36803. * @psalm-param non-empty-string $file
  36804. * @psalm-param positive-int $line
  36805. *
  36806. * @throws InvalidArgumentException
  36807. * @throws UnknownEventTypeException
  36808. */
  36809. public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
  36810. {
  36811. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\NoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
  36812. }
  36813. /**
  36814. * @psalm-param non-empty-string $message
  36815. * @psalm-param non-empty-string $file
  36816. * @psalm-param positive-int $line
  36817. *
  36818. * @throws InvalidArgumentException
  36819. * @throws UnknownEventTypeException
  36820. */
  36821. public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
  36822. {
  36823. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpNoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
  36824. }
  36825. /**
  36826. * @psalm-param non-empty-string $message
  36827. * @psalm-param non-empty-string $file
  36828. * @psalm-param positive-int $line
  36829. *
  36830. * @throws InvalidArgumentException
  36831. * @throws UnknownEventTypeException
  36832. */
  36833. public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
  36834. {
  36835. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\WarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
  36836. }
  36837. /**
  36838. * @psalm-param non-empty-string $message
  36839. * @psalm-param non-empty-string $file
  36840. * @psalm-param positive-int $line
  36841. *
  36842. * @throws InvalidArgumentException
  36843. * @throws UnknownEventTypeException
  36844. */
  36845. public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
  36846. {
  36847. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpWarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
  36848. }
  36849. /**
  36850. * @psalm-param non-empty-string $message
  36851. *
  36852. * @throws InvalidArgumentException
  36853. * @throws UnknownEventTypeException
  36854. */
  36855. public function testTriggeredPhpunitError(\PHPUnit\Event\Code\Test $test, string $message): void
  36856. {
  36857. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitErrorTriggered($this->telemetryInfo(), $test, $message));
  36858. }
  36859. /**
  36860. * @psalm-param non-empty-string $message
  36861. *
  36862. * @throws InvalidArgumentException
  36863. * @throws UnknownEventTypeException
  36864. */
  36865. public function testTriggeredPhpunitWarning(\PHPUnit\Event\Code\Test $test, string $message): void
  36866. {
  36867. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitWarningTriggered($this->telemetryInfo(), $test, $message));
  36868. }
  36869. /**
  36870. * @psalm-param non-empty-string $output
  36871. *
  36872. * @throws InvalidArgumentException
  36873. * @throws UnknownEventTypeException
  36874. */
  36875. public function testPrintedUnexpectedOutput(string $output): void
  36876. {
  36877. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PrintedUnexpectedOutput($this->telemetryInfo(), $output));
  36878. }
  36879. /**
  36880. * @throws InvalidArgumentException
  36881. * @throws UnknownEventTypeException
  36882. */
  36883. public function testFinished(\PHPUnit\Event\Code\Test $test, int $numberOfAssertionsPerformed): void
  36884. {
  36885. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Finished($this->telemetryInfo(), $test, $numberOfAssertionsPerformed));
  36886. }
  36887. /**
  36888. * @psalm-param class-string $testClassName
  36889. *
  36890. * @throws InvalidArgumentException
  36891. * @throws UnknownEventTypeException
  36892. */
  36893. public function testPostConditionCalled(string $testClassName, ClassMethod $calledMethod): void
  36894. {
  36895. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36896. }
  36897. /**
  36898. * @psalm-param class-string $testClassName
  36899. *
  36900. * @throws InvalidArgumentException
  36901. * @throws UnknownEventTypeException
  36902. */
  36903. public function testPostConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36904. {
  36905. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36906. }
  36907. /**
  36908. * @psalm-param class-string $testClassName
  36909. *
  36910. * @throws InvalidArgumentException
  36911. * @throws UnknownEventTypeException
  36912. */
  36913. public function testAfterTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
  36914. {
  36915. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36916. }
  36917. /**
  36918. * @psalm-param class-string $testClassName
  36919. *
  36920. * @throws InvalidArgumentException
  36921. * @throws UnknownEventTypeException
  36922. */
  36923. public function testAfterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36924. {
  36925. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36926. }
  36927. /**
  36928. * @psalm-param class-string $testClassName
  36929. *
  36930. * @throws InvalidArgumentException
  36931. * @throws UnknownEventTypeException
  36932. */
  36933. public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
  36934. {
  36935. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
  36936. }
  36937. /**
  36938. * @psalm-param class-string $testClassName
  36939. *
  36940. * @throws InvalidArgumentException
  36941. * @throws UnknownEventTypeException
  36942. */
  36943. public function testAfterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
  36944. {
  36945. $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
  36946. }
  36947. /**
  36948. * @throws InvalidArgumentException
  36949. * @throws UnknownEventTypeException
  36950. */
  36951. public function testSuiteFinished(TestSuite $testSuite): void
  36952. {
  36953. $this->dispatcher->dispatch(new TestSuiteFinished($this->telemetryInfo(), $testSuite));
  36954. }
  36955. /**
  36956. * @throws InvalidArgumentException
  36957. * @throws UnknownEventTypeException
  36958. */
  36959. public function testRunnerTriggeredDeprecation(string $message): void
  36960. {
  36961. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\DeprecationTriggered($this->telemetryInfo(), $message));
  36962. }
  36963. /**
  36964. * @throws InvalidArgumentException
  36965. * @throws UnknownEventTypeException
  36966. */
  36967. public function testRunnerTriggeredWarning(string $message): void
  36968. {
  36969. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\WarningTriggered($this->telemetryInfo(), $message));
  36970. }
  36971. /**
  36972. * @throws InvalidArgumentException
  36973. * @throws UnknownEventTypeException
  36974. */
  36975. public function testRunnerEnabledGarbageCollection(): void
  36976. {
  36977. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionEnabled($this->telemetryInfo()));
  36978. }
  36979. /**
  36980. * @throws InvalidArgumentException
  36981. * @throws UnknownEventTypeException
  36982. */
  36983. public function testRunnerExecutionAborted(): void
  36984. {
  36985. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionAborted($this->telemetryInfo()));
  36986. }
  36987. /**
  36988. * @throws InvalidArgumentException
  36989. * @throws UnknownEventTypeException
  36990. */
  36991. public function testRunnerExecutionFinished(): void
  36992. {
  36993. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionFinished($this->telemetryInfo()));
  36994. }
  36995. /**
  36996. * @throws InvalidArgumentException
  36997. * @throws UnknownEventTypeException
  36998. */
  36999. public function testRunnerFinished(): void
  37000. {
  37001. $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Finished($this->telemetryInfo()));
  37002. }
  37003. /**
  37004. * @throws InvalidArgumentException
  37005. * @throws UnknownEventTypeException
  37006. */
  37007. public function applicationFinished(int $shellExitCode): void
  37008. {
  37009. $this->dispatcher->dispatch(new \PHPUnit\Event\Application\Finished($this->telemetryInfo(), $shellExitCode));
  37010. }
  37011. /**
  37012. * @throws InvalidArgumentException
  37013. */
  37014. private function telemetryInfo(): \PHPUnit\Event\Telemetry\Info
  37015. {
  37016. $current = $this->system->snapshot();
  37017. $info = new \PHPUnit\Event\Telemetry\Info($current, $current->time()->duration($this->startSnapshot->time()), $current->memoryUsage()->diff($this->startSnapshot->memoryUsage()), $current->time()->duration($this->previousSnapshot->time()), $current->memoryUsage()->diff($this->previousSnapshot->memoryUsage()));
  37018. $this->previousSnapshot = $current;
  37019. return $info;
  37020. }
  37021. }
  37022. <?php
  37023. declare (strict_types=1);
  37024. /*
  37025. * This file is part of PHPUnit.
  37026. *
  37027. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37028. *
  37029. * For the full copyright and license information, please view the LICENSE
  37030. * file that was distributed with this source code.
  37031. */
  37032. namespace PHPUnit\Event;
  37033. use PHPUnit\Event\Code\ClassMethod;
  37034. use PHPUnit\Event\Code\ComparisonFailure;
  37035. use PHPUnit\Event\Code\Throwable;
  37036. use PHPUnit\Event\TestSuite\TestSuite;
  37037. use PHPUnit\Framework\Constraint;
  37038. use PHPUnit\TextUI\Configuration\Configuration;
  37039. /**
  37040. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37041. *
  37042. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  37043. */
  37044. interface Emitter
  37045. {
  37046. /**
  37047. * @deprecated
  37048. */
  37049. public function exportObjects(): void;
  37050. /**
  37051. * @deprecated
  37052. */
  37053. public function exportsObjects(): bool;
  37054. public function applicationStarted(): void;
  37055. public function testRunnerStarted(): void;
  37056. public function testRunnerConfigured(Configuration $configuration): void;
  37057. public function testRunnerBootstrapFinished(string $filename): void;
  37058. public function testRunnerLoadedExtensionFromPhar(string $filename, string $name, string $version): void;
  37059. /**
  37060. * @psalm-param class-string $className
  37061. * @psalm-param array<string, string> $parameters
  37062. */
  37063. public function testRunnerBootstrappedExtension(string $className, array $parameters): void;
  37064. public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod): void;
  37065. public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods): void;
  37066. public function testSuiteLoaded(TestSuite $testSuite): void;
  37067. public function testSuiteFiltered(TestSuite $testSuite): void;
  37068. public function testSuiteSorted(int $executionOrder, int $executionOrderDefects, bool $resolveDependencies): void;
  37069. public function testRunnerEventFacadeSealed(): void;
  37070. public function testRunnerExecutionStarted(TestSuite $testSuite): void;
  37071. public function testRunnerDisabledGarbageCollection(): void;
  37072. public function testRunnerTriggeredGarbageCollection(): void;
  37073. public function testSuiteSkipped(TestSuite $testSuite, string $message): void;
  37074. public function testSuiteStarted(TestSuite $testSuite): void;
  37075. public function testPreparationStarted(\PHPUnit\Event\Code\Test $test): void;
  37076. public function testPreparationFailed(\PHPUnit\Event\Code\Test $test): void;
  37077. /**
  37078. * @psalm-param class-string $testClassName
  37079. */
  37080. public function testBeforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
  37081. /**
  37082. * @psalm-param class-string $testClassName
  37083. */
  37084. public function testBeforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
  37085. /**
  37086. * @psalm-param class-string $testClassName
  37087. */
  37088. public function testBeforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37089. /**
  37090. * @psalm-param class-string $testClassName
  37091. */
  37092. public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
  37093. /**
  37094. * @psalm-param class-string $testClassName
  37095. */
  37096. public function testBeforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37097. /**
  37098. * @psalm-param class-string $testClassName
  37099. */
  37100. public function testPreConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
  37101. /**
  37102. * @psalm-param class-string $testClassName
  37103. */
  37104. public function testPreConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37105. public function testPrepared(\PHPUnit\Event\Code\Test $test): void;
  37106. /**
  37107. * @psalm-param class-string $className
  37108. */
  37109. public function testRegisteredComparator(string $className): void;
  37110. /**
  37111. * @deprecated
  37112. */
  37113. public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message): void;
  37114. /**
  37115. * @deprecated
  37116. */
  37117. public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message): void;
  37118. /**
  37119. * @psalm-param class-string $className
  37120. */
  37121. public function testCreatedMockObject(string $className): void;
  37122. /**
  37123. * @psalm-param list<class-string> $interfaces
  37124. */
  37125. public function testCreatedMockObjectForIntersectionOfInterfaces(array $interfaces): void;
  37126. /**
  37127. * @psalm-param trait-string $traitName
  37128. */
  37129. public function testCreatedMockObjectForTrait(string $traitName): void;
  37130. /**
  37131. * @psalm-param class-string $className
  37132. */
  37133. public function testCreatedMockObjectForAbstractClass(string $className): void;
  37134. /**
  37135. * @psalm-param class-string $originalClassName
  37136. * @psalm-param class-string $mockClassName
  37137. */
  37138. public function testCreatedMockObjectFromWsdl(string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options): void;
  37139. /**
  37140. * @psalm-param class-string $className
  37141. */
  37142. public function testCreatedPartialMockObject(string $className, string ...$methodNames): void;
  37143. /**
  37144. * @psalm-param class-string $className
  37145. */
  37146. public function testCreatedTestProxy(string $className, array $constructorArguments): void;
  37147. /**
  37148. * @psalm-param class-string $className
  37149. */
  37150. public function testCreatedStub(string $className): void;
  37151. /**
  37152. * @psalm-param list<class-string> $interfaces
  37153. */
  37154. public function testCreatedStubForIntersectionOfInterfaces(array $interfaces): void;
  37155. public function testErrored(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void;
  37156. public function testFailed(\PHPUnit\Event\Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure): void;
  37157. public function testPassed(\PHPUnit\Event\Code\Test $test): void;
  37158. /**
  37159. * @psalm-param non-empty-string $message
  37160. */
  37161. public function testConsideredRisky(\PHPUnit\Event\Code\Test $test, string $message): void;
  37162. public function testMarkedAsIncomplete(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void;
  37163. /**
  37164. * @psalm-param non-empty-string $message
  37165. */
  37166. public function testSkipped(\PHPUnit\Event\Code\Test $test, string $message): void;
  37167. /**
  37168. * @psalm-param non-empty-string $message
  37169. */
  37170. public function testTriggeredPhpunitDeprecation(\PHPUnit\Event\Code\Test $test, string $message): void;
  37171. /**
  37172. * @psalm-param non-empty-string $message
  37173. * @psalm-param non-empty-string $file
  37174. * @psalm-param positive-int $line
  37175. */
  37176. public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void;
  37177. /**
  37178. * @psalm-param non-empty-string $message
  37179. * @psalm-param non-empty-string $file
  37180. * @psalm-param positive-int $line
  37181. */
  37182. public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void;
  37183. /**
  37184. * @psalm-param non-empty-string $message
  37185. * @psalm-param non-empty-string $file
  37186. * @psalm-param positive-int $line
  37187. */
  37188. public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed): void;
  37189. /**
  37190. * @psalm-param non-empty-string $message
  37191. * @psalm-param non-empty-string $file
  37192. * @psalm-param positive-int $line
  37193. */
  37194. public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
  37195. /**
  37196. * @psalm-param non-empty-string $message
  37197. * @psalm-param non-empty-string $file
  37198. * @psalm-param positive-int $line
  37199. */
  37200. public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
  37201. /**
  37202. * @psalm-param non-empty-string $message
  37203. * @psalm-param non-empty-string $file
  37204. * @psalm-param positive-int $line
  37205. */
  37206. public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
  37207. /**
  37208. * @psalm-param non-empty-string $message
  37209. * @psalm-param non-empty-string $file
  37210. * @psalm-param positive-int $line
  37211. */
  37212. public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
  37213. /**
  37214. * @psalm-param non-empty-string $message
  37215. */
  37216. public function testTriggeredPhpunitError(\PHPUnit\Event\Code\Test $test, string $message): void;
  37217. /**
  37218. * @psalm-param non-empty-string $message
  37219. */
  37220. public function testTriggeredPhpunitWarning(\PHPUnit\Event\Code\Test $test, string $message): void;
  37221. /**
  37222. * @psalm-param non-empty-string $output
  37223. */
  37224. public function testPrintedUnexpectedOutput(string $output): void;
  37225. public function testFinished(\PHPUnit\Event\Code\Test $test, int $numberOfAssertionsPerformed): void;
  37226. /**
  37227. * @psalm-param class-string $testClassName
  37228. */
  37229. public function testPostConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
  37230. /**
  37231. * @psalm-param class-string $testClassName
  37232. */
  37233. public function testPostConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37234. /**
  37235. * @psalm-param class-string $testClassName
  37236. */
  37237. public function testAfterTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
  37238. /**
  37239. * @psalm-param class-string $testClassName
  37240. */
  37241. public function testAfterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37242. /**
  37243. * @psalm-param class-string $testClassName
  37244. */
  37245. public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
  37246. /**
  37247. * @psalm-param class-string $testClassName
  37248. */
  37249. public function testAfterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
  37250. public function testSuiteFinished(TestSuite $testSuite): void;
  37251. public function testRunnerTriggeredDeprecation(string $message): void;
  37252. public function testRunnerTriggeredWarning(string $message): void;
  37253. public function testRunnerEnabledGarbageCollection(): void;
  37254. public function testRunnerExecutionAborted(): void;
  37255. public function testRunnerExecutionFinished(): void;
  37256. public function testRunnerFinished(): void;
  37257. public function applicationFinished(int $shellExitCode): void;
  37258. }
  37259. <?php
  37260. declare (strict_types=1);
  37261. /*
  37262. * This file is part of PHPUnit.
  37263. *
  37264. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37265. *
  37266. * For the full copyright and license information, please view the LICENSE
  37267. * file that was distributed with this source code.
  37268. */
  37269. namespace PHPUnit\Event\Application;
  37270. use function sprintf;
  37271. use PHPUnit\Event\Event;
  37272. use PHPUnit\Event\Telemetry;
  37273. /**
  37274. * @psalm-immutable
  37275. *
  37276. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37277. */
  37278. final class Finished implements Event
  37279. {
  37280. private readonly Telemetry\Info $telemetryInfo;
  37281. private readonly int $shellExitCode;
  37282. public function __construct(Telemetry\Info $telemetryInfo, int $shellExitCode)
  37283. {
  37284. $this->telemetryInfo = $telemetryInfo;
  37285. $this->shellExitCode = $shellExitCode;
  37286. }
  37287. public function telemetryInfo(): Telemetry\Info
  37288. {
  37289. return $this->telemetryInfo;
  37290. }
  37291. public function shellExitCode(): int
  37292. {
  37293. return $this->shellExitCode;
  37294. }
  37295. public function asString(): string
  37296. {
  37297. return sprintf('PHPUnit Finished (Shell Exit Code: %d)', $this->shellExitCode);
  37298. }
  37299. }
  37300. <?php
  37301. declare (strict_types=1);
  37302. /*
  37303. * This file is part of PHPUnit.
  37304. *
  37305. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37306. *
  37307. * For the full copyright and license information, please view the LICENSE
  37308. * file that was distributed with this source code.
  37309. */
  37310. namespace PHPUnit\Event\Application;
  37311. use PHPUnit\Event\Subscriber;
  37312. /**
  37313. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37314. */
  37315. interface FinishedSubscriber extends Subscriber
  37316. {
  37317. public function notify(\PHPUnit\Event\Application\Finished $event): void;
  37318. }
  37319. <?php
  37320. declare (strict_types=1);
  37321. /*
  37322. * This file is part of PHPUnit.
  37323. *
  37324. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37325. *
  37326. * For the full copyright and license information, please view the LICENSE
  37327. * file that was distributed with this source code.
  37328. */
  37329. namespace PHPUnit\Event\Application;
  37330. use function sprintf;
  37331. use PHPUnit\Event\Event;
  37332. use PHPUnit\Event\Runtime\Runtime;
  37333. use PHPUnit\Event\Telemetry;
  37334. /**
  37335. * @psalm-immutable
  37336. *
  37337. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37338. */
  37339. final class Started implements Event
  37340. {
  37341. private readonly Telemetry\Info $telemetryInfo;
  37342. private readonly Runtime $runtime;
  37343. public function __construct(Telemetry\Info $telemetryInfo, Runtime $runtime)
  37344. {
  37345. $this->telemetryInfo = $telemetryInfo;
  37346. $this->runtime = $runtime;
  37347. }
  37348. public function telemetryInfo(): Telemetry\Info
  37349. {
  37350. return $this->telemetryInfo;
  37351. }
  37352. public function runtime(): Runtime
  37353. {
  37354. return $this->runtime;
  37355. }
  37356. public function asString(): string
  37357. {
  37358. return sprintf('PHPUnit Started (%s)', $this->runtime->asString());
  37359. }
  37360. }
  37361. <?php
  37362. declare (strict_types=1);
  37363. /*
  37364. * This file is part of PHPUnit.
  37365. *
  37366. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37367. *
  37368. * For the full copyright and license information, please view the LICENSE
  37369. * file that was distributed with this source code.
  37370. */
  37371. namespace PHPUnit\Event\Application;
  37372. use PHPUnit\Event\Subscriber;
  37373. /**
  37374. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37375. */
  37376. interface StartedSubscriber extends Subscriber
  37377. {
  37378. public function notify(\PHPUnit\Event\Application\Started $event): void;
  37379. }
  37380. <?php
  37381. declare (strict_types=1);
  37382. /*
  37383. * This file is part of PHPUnit.
  37384. *
  37385. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37386. *
  37387. * For the full copyright and license information, please view the LICENSE
  37388. * file that was distributed with this source code.
  37389. */
  37390. namespace PHPUnit\Event;
  37391. /**
  37392. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37393. */
  37394. interface Event
  37395. {
  37396. public function telemetryInfo(): \PHPUnit\Event\Telemetry\Info;
  37397. public function asString(): string;
  37398. }
  37399. <?php
  37400. declare (strict_types=1);
  37401. /*
  37402. * This file is part of PHPUnit.
  37403. *
  37404. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37405. *
  37406. * For the full copyright and license information, please view the LICENSE
  37407. * file that was distributed with this source code.
  37408. */
  37409. namespace PHPUnit\Event;
  37410. use function count;
  37411. use Countable;
  37412. use IteratorAggregate;
  37413. /**
  37414. * @template-implements IteratorAggregate<int, Event>
  37415. *
  37416. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37417. */
  37418. final class EventCollection implements Countable, IteratorAggregate
  37419. {
  37420. /**
  37421. * @psalm-var list<Event>
  37422. */
  37423. private array $events = [];
  37424. public function add(\PHPUnit\Event\Event ...$events): void
  37425. {
  37426. foreach ($events as $event) {
  37427. $this->events[] = $event;
  37428. }
  37429. }
  37430. /**
  37431. * @psalm-return list<Event>
  37432. */
  37433. public function asArray(): array
  37434. {
  37435. return $this->events;
  37436. }
  37437. public function count(): int
  37438. {
  37439. return count($this->events);
  37440. }
  37441. public function isEmpty(): bool
  37442. {
  37443. return $this->count() === 0;
  37444. }
  37445. public function isNotEmpty(): bool
  37446. {
  37447. return $this->count() > 0;
  37448. }
  37449. public function getIterator(): \PHPUnit\Event\EventCollectionIterator
  37450. {
  37451. return new \PHPUnit\Event\EventCollectionIterator($this);
  37452. }
  37453. }
  37454. <?php
  37455. declare (strict_types=1);
  37456. /*
  37457. * This file is part of PHPUnit.
  37458. *
  37459. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37460. *
  37461. * For the full copyright and license information, please view the LICENSE
  37462. * file that was distributed with this source code.
  37463. */
  37464. namespace PHPUnit\Event;
  37465. use function count;
  37466. use Iterator;
  37467. /**
  37468. * @template-implements Iterator<int, Event>
  37469. *
  37470. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37471. */
  37472. final class EventCollectionIterator implements Iterator
  37473. {
  37474. /**
  37475. * @psalm-var list<Event>
  37476. */
  37477. private readonly array $events;
  37478. private int $position = 0;
  37479. public function __construct(\PHPUnit\Event\EventCollection $events)
  37480. {
  37481. $this->events = $events->asArray();
  37482. }
  37483. public function rewind(): void
  37484. {
  37485. $this->position = 0;
  37486. }
  37487. public function valid(): bool
  37488. {
  37489. return $this->position < count($this->events);
  37490. }
  37491. public function key(): int
  37492. {
  37493. return $this->position;
  37494. }
  37495. public function current(): \PHPUnit\Event\Event
  37496. {
  37497. return $this->events[$this->position];
  37498. }
  37499. public function next(): void
  37500. {
  37501. $this->position++;
  37502. }
  37503. }
  37504. <?php
  37505. declare (strict_types=1);
  37506. /*
  37507. * This file is part of PHPUnit.
  37508. *
  37509. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37510. *
  37511. * For the full copyright and license information, please view the LICENSE
  37512. * file that was distributed with this source code.
  37513. */
  37514. namespace PHPUnit\Event\Test;
  37515. use function sprintf;
  37516. use PHPUnit\Event\Event;
  37517. use PHPUnit\Event\Telemetry;
  37518. /**
  37519. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37520. *
  37521. * @deprecated
  37522. */
  37523. final class AssertionFailed implements Event
  37524. {
  37525. private readonly Telemetry\Info $telemetryInfo;
  37526. private readonly string $value;
  37527. private readonly string $constraint;
  37528. private readonly int $count;
  37529. private readonly string $message;
  37530. public function __construct(Telemetry\Info $telemetryInfo, string $value, string $constraint, int $count, string $message)
  37531. {
  37532. $this->telemetryInfo = $telemetryInfo;
  37533. $this->value = $value;
  37534. $this->constraint = $constraint;
  37535. $this->count = $count;
  37536. $this->message = $message;
  37537. }
  37538. public function telemetryInfo(): Telemetry\Info
  37539. {
  37540. return $this->telemetryInfo;
  37541. }
  37542. public function value(): string
  37543. {
  37544. return $this->value;
  37545. }
  37546. public function count(): int
  37547. {
  37548. return $this->count;
  37549. }
  37550. public function message(): string
  37551. {
  37552. return $this->message;
  37553. }
  37554. public function asString(): string
  37555. {
  37556. $message = '';
  37557. if (!empty($this->message)) {
  37558. $message = sprintf(', Message: %s', $this->message);
  37559. }
  37560. return sprintf('Assertion Failed (Constraint: %s, Value: %s%s)', $this->constraint, $this->value, $message);
  37561. }
  37562. }
  37563. <?php
  37564. declare (strict_types=1);
  37565. /*
  37566. * This file is part of PHPUnit.
  37567. *
  37568. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37569. *
  37570. * For the full copyright and license information, please view the LICENSE
  37571. * file that was distributed with this source code.
  37572. */
  37573. namespace PHPUnit\Event\Test;
  37574. use PHPUnit\Event\Subscriber;
  37575. /**
  37576. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37577. *
  37578. * @deprecated
  37579. */
  37580. interface AssertionFailedSubscriber extends Subscriber
  37581. {
  37582. public function notify(\PHPUnit\Event\Test\AssertionFailed $event): void;
  37583. }
  37584. <?php
  37585. declare (strict_types=1);
  37586. /*
  37587. * This file is part of PHPUnit.
  37588. *
  37589. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37590. *
  37591. * For the full copyright and license information, please view the LICENSE
  37592. * file that was distributed with this source code.
  37593. */
  37594. namespace PHPUnit\Event\Test;
  37595. use function sprintf;
  37596. use PHPUnit\Event\Event;
  37597. use PHPUnit\Event\Telemetry;
  37598. /**
  37599. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37600. *
  37601. * @deprecated
  37602. */
  37603. final class AssertionSucceeded implements Event
  37604. {
  37605. private readonly Telemetry\Info $telemetryInfo;
  37606. private readonly string $value;
  37607. private readonly string $constraint;
  37608. private readonly int $count;
  37609. private readonly string $message;
  37610. public function __construct(Telemetry\Info $telemetryInfo, string $value, string $constraint, int $count, string $message)
  37611. {
  37612. $this->telemetryInfo = $telemetryInfo;
  37613. $this->value = $value;
  37614. $this->constraint = $constraint;
  37615. $this->count = $count;
  37616. $this->message = $message;
  37617. }
  37618. public function telemetryInfo(): Telemetry\Info
  37619. {
  37620. return $this->telemetryInfo;
  37621. }
  37622. public function value(): string
  37623. {
  37624. return $this->value;
  37625. }
  37626. public function count(): int
  37627. {
  37628. return $this->count;
  37629. }
  37630. public function message(): string
  37631. {
  37632. return $this->message;
  37633. }
  37634. public function asString(): string
  37635. {
  37636. $message = '';
  37637. if (!empty($this->message)) {
  37638. $message = sprintf(', Message: %s', $this->message);
  37639. }
  37640. return sprintf('Assertion Succeeded (Constraint: %s, Value: %s%s)', $this->constraint, $this->value, $message);
  37641. }
  37642. }
  37643. <?php
  37644. declare (strict_types=1);
  37645. /*
  37646. * This file is part of PHPUnit.
  37647. *
  37648. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37649. *
  37650. * For the full copyright and license information, please view the LICENSE
  37651. * file that was distributed with this source code.
  37652. */
  37653. namespace PHPUnit\Event\Test;
  37654. use PHPUnit\Event\Subscriber;
  37655. /**
  37656. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37657. *
  37658. * @deprecated
  37659. */
  37660. interface AssertionSucceededSubscriber extends Subscriber
  37661. {
  37662. public function notify(\PHPUnit\Event\Test\AssertionSucceeded $event): void;
  37663. }
  37664. <?php
  37665. declare (strict_types=1);
  37666. /*
  37667. * This file is part of PHPUnit.
  37668. *
  37669. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37670. *
  37671. * For the full copyright and license information, please view the LICENSE
  37672. * file that was distributed with this source code.
  37673. */
  37674. namespace PHPUnit\Event\Test;
  37675. use function sprintf;
  37676. use PHPUnit\Event\Event;
  37677. use PHPUnit\Event\Telemetry;
  37678. /**
  37679. * @psalm-immutable
  37680. *
  37681. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37682. */
  37683. final class ComparatorRegistered implements Event
  37684. {
  37685. private readonly Telemetry\Info $telemetryInfo;
  37686. /**
  37687. * @psalm-var class-string
  37688. */
  37689. private readonly string $className;
  37690. /**
  37691. * @psalm-param class-string $className
  37692. */
  37693. public function __construct(Telemetry\Info $telemetryInfo, string $className)
  37694. {
  37695. $this->telemetryInfo = $telemetryInfo;
  37696. $this->className = $className;
  37697. }
  37698. public function telemetryInfo(): Telemetry\Info
  37699. {
  37700. return $this->telemetryInfo;
  37701. }
  37702. /**
  37703. * @psalm-return class-string
  37704. */
  37705. public function className(): string
  37706. {
  37707. return $this->className;
  37708. }
  37709. public function asString(): string
  37710. {
  37711. return sprintf('Comparator Registered (%s)', $this->className);
  37712. }
  37713. }
  37714. <?php
  37715. declare (strict_types=1);
  37716. /*
  37717. * This file is part of PHPUnit.
  37718. *
  37719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37720. *
  37721. * For the full copyright and license information, please view the LICENSE
  37722. * file that was distributed with this source code.
  37723. */
  37724. namespace PHPUnit\Event\Test;
  37725. use PHPUnit\Event\Subscriber;
  37726. /**
  37727. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37728. */
  37729. interface ComparatorRegisteredSubscriber extends Subscriber
  37730. {
  37731. public function notify(\PHPUnit\Event\Test\ComparatorRegistered $event): void;
  37732. }
  37733. <?php
  37734. declare (strict_types=1);
  37735. /*
  37736. * This file is part of PHPUnit.
  37737. *
  37738. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37739. *
  37740. * For the full copyright and license information, please view the LICENSE
  37741. * file that was distributed with this source code.
  37742. */
  37743. namespace PHPUnit\Event\Test;
  37744. use function sprintf;
  37745. use PHPUnit\Event\Code;
  37746. use PHPUnit\Event\Event;
  37747. use PHPUnit\Event\Telemetry;
  37748. /**
  37749. * @psalm-immutable
  37750. *
  37751. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37752. */
  37753. final class AfterLastTestMethodCalled implements Event
  37754. {
  37755. private readonly Telemetry\Info $telemetryInfo;
  37756. /**
  37757. * @psalm-var class-string
  37758. */
  37759. private readonly string $testClassName;
  37760. private readonly Code\ClassMethod $calledMethod;
  37761. /**
  37762. * @psalm-param class-string $testClassName
  37763. */
  37764. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  37765. {
  37766. $this->telemetryInfo = $telemetryInfo;
  37767. $this->testClassName = $testClassName;
  37768. $this->calledMethod = $calledMethod;
  37769. }
  37770. public function telemetryInfo(): Telemetry\Info
  37771. {
  37772. return $this->telemetryInfo;
  37773. }
  37774. /**
  37775. * @psalm-return class-string
  37776. */
  37777. public function testClassName(): string
  37778. {
  37779. return $this->testClassName;
  37780. }
  37781. public function calledMethod(): Code\ClassMethod
  37782. {
  37783. return $this->calledMethod;
  37784. }
  37785. public function asString(): string
  37786. {
  37787. return sprintf('After Last Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  37788. }
  37789. }
  37790. <?php
  37791. declare (strict_types=1);
  37792. /*
  37793. * This file is part of PHPUnit.
  37794. *
  37795. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37796. *
  37797. * For the full copyright and license information, please view the LICENSE
  37798. * file that was distributed with this source code.
  37799. */
  37800. namespace PHPUnit\Event\Test;
  37801. use PHPUnit\Event\Subscriber;
  37802. /**
  37803. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37804. */
  37805. interface AfterLastTestMethodCalledSubscriber extends Subscriber
  37806. {
  37807. public function notify(\PHPUnit\Event\Test\AfterLastTestMethodCalled $event): void;
  37808. }
  37809. <?php
  37810. declare (strict_types=1);
  37811. /*
  37812. * This file is part of PHPUnit.
  37813. *
  37814. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37815. *
  37816. * For the full copyright and license information, please view the LICENSE
  37817. * file that was distributed with this source code.
  37818. */
  37819. namespace PHPUnit\Event\Test;
  37820. use const PHP_EOL;
  37821. use function sprintf;
  37822. use PHPUnit\Event\Code;
  37823. use PHPUnit\Event\Event;
  37824. use PHPUnit\Event\Telemetry;
  37825. /**
  37826. * @psalm-immutable
  37827. *
  37828. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37829. */
  37830. final class AfterLastTestMethodFinished implements Event
  37831. {
  37832. private readonly Telemetry\Info $telemetryInfo;
  37833. /**
  37834. * @psalm-var class-string
  37835. */
  37836. private readonly string $testClassName;
  37837. /**
  37838. * @psalm-var list<Code\ClassMethod>
  37839. */
  37840. private readonly array $calledMethods;
  37841. /**
  37842. * @psalm-param class-string $testClassName
  37843. */
  37844. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  37845. {
  37846. $this->telemetryInfo = $telemetryInfo;
  37847. $this->testClassName = $testClassName;
  37848. $this->calledMethods = $calledMethods;
  37849. }
  37850. public function telemetryInfo(): Telemetry\Info
  37851. {
  37852. return $this->telemetryInfo;
  37853. }
  37854. /**
  37855. * @psalm-return class-string
  37856. */
  37857. public function testClassName(): string
  37858. {
  37859. return $this->testClassName;
  37860. }
  37861. /**
  37862. * @psalm-return list<Code\ClassMethod>
  37863. */
  37864. public function calledMethods(): array
  37865. {
  37866. return $this->calledMethods;
  37867. }
  37868. public function asString(): string
  37869. {
  37870. $buffer = 'After Last Test Method Finished:';
  37871. foreach ($this->calledMethods as $calledMethod) {
  37872. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  37873. }
  37874. return $buffer;
  37875. }
  37876. }
  37877. <?php
  37878. declare (strict_types=1);
  37879. /*
  37880. * This file is part of PHPUnit.
  37881. *
  37882. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37883. *
  37884. * For the full copyright and license information, please view the LICENSE
  37885. * file that was distributed with this source code.
  37886. */
  37887. namespace PHPUnit\Event\Test;
  37888. use PHPUnit\Event\Subscriber;
  37889. /**
  37890. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37891. */
  37892. interface AfterLastTestMethodFinishedSubscriber extends Subscriber
  37893. {
  37894. public function notify(\PHPUnit\Event\Test\AfterLastTestMethodFinished $event): void;
  37895. }
  37896. <?php
  37897. declare (strict_types=1);
  37898. /*
  37899. * This file is part of PHPUnit.
  37900. *
  37901. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37902. *
  37903. * For the full copyright and license information, please view the LICENSE
  37904. * file that was distributed with this source code.
  37905. */
  37906. namespace PHPUnit\Event\Test;
  37907. use function sprintf;
  37908. use PHPUnit\Event\Code;
  37909. use PHPUnit\Event\Event;
  37910. use PHPUnit\Event\Telemetry;
  37911. /**
  37912. * @psalm-immutable
  37913. *
  37914. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37915. */
  37916. final class AfterTestMethodCalled implements Event
  37917. {
  37918. private readonly Telemetry\Info $telemetryInfo;
  37919. /**
  37920. * @psalm-var class-string
  37921. */
  37922. private readonly string $testClassName;
  37923. private readonly Code\ClassMethod $calledMethod;
  37924. /**
  37925. * @psalm-param class-string $testClassName
  37926. */
  37927. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  37928. {
  37929. $this->telemetryInfo = $telemetryInfo;
  37930. $this->testClassName = $testClassName;
  37931. $this->calledMethod = $calledMethod;
  37932. }
  37933. public function telemetryInfo(): Telemetry\Info
  37934. {
  37935. return $this->telemetryInfo;
  37936. }
  37937. /**
  37938. * @psalm-return class-string
  37939. */
  37940. public function testClassName(): string
  37941. {
  37942. return $this->testClassName;
  37943. }
  37944. public function calledMethod(): Code\ClassMethod
  37945. {
  37946. return $this->calledMethod;
  37947. }
  37948. public function asString(): string
  37949. {
  37950. return sprintf('After Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  37951. }
  37952. }
  37953. <?php
  37954. declare (strict_types=1);
  37955. /*
  37956. * This file is part of PHPUnit.
  37957. *
  37958. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37959. *
  37960. * For the full copyright and license information, please view the LICENSE
  37961. * file that was distributed with this source code.
  37962. */
  37963. namespace PHPUnit\Event\Test;
  37964. use PHPUnit\Event\Subscriber;
  37965. /**
  37966. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37967. */
  37968. interface AfterTestMethodCalledSubscriber extends Subscriber
  37969. {
  37970. public function notify(\PHPUnit\Event\Test\AfterTestMethodCalled $event): void;
  37971. }
  37972. <?php
  37973. declare (strict_types=1);
  37974. /*
  37975. * This file is part of PHPUnit.
  37976. *
  37977. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37978. *
  37979. * For the full copyright and license information, please view the LICENSE
  37980. * file that was distributed with this source code.
  37981. */
  37982. namespace PHPUnit\Event\Test;
  37983. use const PHP_EOL;
  37984. use function sprintf;
  37985. use PHPUnit\Event\Code;
  37986. use PHPUnit\Event\Event;
  37987. use PHPUnit\Event\Telemetry;
  37988. /**
  37989. * @psalm-immutable
  37990. *
  37991. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  37992. */
  37993. final class AfterTestMethodFinished implements Event
  37994. {
  37995. private readonly Telemetry\Info $telemetryInfo;
  37996. /**
  37997. * @psalm-var class-string
  37998. */
  37999. private readonly string $testClassName;
  38000. /**
  38001. * @psalm-var list<Code\ClassMethod>
  38002. */
  38003. private readonly array $calledMethods;
  38004. /**
  38005. * @psalm-param class-string $testClassName
  38006. */
  38007. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  38008. {
  38009. $this->telemetryInfo = $telemetryInfo;
  38010. $this->testClassName = $testClassName;
  38011. $this->calledMethods = $calledMethods;
  38012. }
  38013. public function telemetryInfo(): Telemetry\Info
  38014. {
  38015. return $this->telemetryInfo;
  38016. }
  38017. /**
  38018. * @psalm-return class-string
  38019. */
  38020. public function testClassName(): string
  38021. {
  38022. return $this->testClassName;
  38023. }
  38024. /**
  38025. * @psalm-return list<Code\ClassMethod>
  38026. */
  38027. public function calledMethods(): array
  38028. {
  38029. return $this->calledMethods;
  38030. }
  38031. public function asString(): string
  38032. {
  38033. $buffer = 'After Test Method Finished:';
  38034. foreach ($this->calledMethods as $calledMethod) {
  38035. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  38036. }
  38037. return $buffer;
  38038. }
  38039. }
  38040. <?php
  38041. declare (strict_types=1);
  38042. /*
  38043. * This file is part of PHPUnit.
  38044. *
  38045. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38046. *
  38047. * For the full copyright and license information, please view the LICENSE
  38048. * file that was distributed with this source code.
  38049. */
  38050. namespace PHPUnit\Event\Test;
  38051. use PHPUnit\Event\Subscriber;
  38052. /**
  38053. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38054. */
  38055. interface AfterTestMethodFinishedSubscriber extends Subscriber
  38056. {
  38057. public function notify(\PHPUnit\Event\Test\AfterTestMethodFinished $event): void;
  38058. }
  38059. <?php
  38060. declare (strict_types=1);
  38061. /*
  38062. * This file is part of PHPUnit.
  38063. *
  38064. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38065. *
  38066. * For the full copyright and license information, please view the LICENSE
  38067. * file that was distributed with this source code.
  38068. */
  38069. namespace PHPUnit\Event\Test;
  38070. use function sprintf;
  38071. use PHPUnit\Event\Code;
  38072. use PHPUnit\Event\Event;
  38073. use PHPUnit\Event\Telemetry;
  38074. /**
  38075. * @psalm-immutable
  38076. *
  38077. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38078. */
  38079. final class BeforeFirstTestMethodCalled implements Event
  38080. {
  38081. private readonly Telemetry\Info $telemetryInfo;
  38082. /**
  38083. * @psalm-var class-string
  38084. */
  38085. private readonly string $testClassName;
  38086. private readonly Code\ClassMethod $calledMethod;
  38087. /**
  38088. * @psalm-param class-string $testClassName
  38089. */
  38090. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  38091. {
  38092. $this->telemetryInfo = $telemetryInfo;
  38093. $this->testClassName = $testClassName;
  38094. $this->calledMethod = $calledMethod;
  38095. }
  38096. public function telemetryInfo(): Telemetry\Info
  38097. {
  38098. return $this->telemetryInfo;
  38099. }
  38100. /**
  38101. * @psalm-return class-string
  38102. */
  38103. public function testClassName(): string
  38104. {
  38105. return $this->testClassName;
  38106. }
  38107. public function calledMethod(): Code\ClassMethod
  38108. {
  38109. return $this->calledMethod;
  38110. }
  38111. public function asString(): string
  38112. {
  38113. return sprintf('Before First Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  38114. }
  38115. }
  38116. <?php
  38117. declare (strict_types=1);
  38118. /*
  38119. * This file is part of PHPUnit.
  38120. *
  38121. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38122. *
  38123. * For the full copyright and license information, please view the LICENSE
  38124. * file that was distributed with this source code.
  38125. */
  38126. namespace PHPUnit\Event\Test;
  38127. use PHPUnit\Event\Subscriber;
  38128. /**
  38129. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38130. */
  38131. interface BeforeFirstTestMethodCalledSubscriber extends Subscriber
  38132. {
  38133. public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodCalled $event): void;
  38134. }
  38135. <?php
  38136. declare (strict_types=1);
  38137. /*
  38138. * This file is part of PHPUnit.
  38139. *
  38140. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38141. *
  38142. * For the full copyright and license information, please view the LICENSE
  38143. * file that was distributed with this source code.
  38144. */
  38145. namespace PHPUnit\Event\Test;
  38146. use const PHP_EOL;
  38147. use function sprintf;
  38148. use PHPUnit\Event\Code;
  38149. use PHPUnit\Event\Code\Throwable;
  38150. use PHPUnit\Event\Event;
  38151. use PHPUnit\Event\Telemetry;
  38152. /**
  38153. * @psalm-immutable
  38154. *
  38155. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38156. */
  38157. final class BeforeFirstTestMethodErrored implements Event
  38158. {
  38159. private readonly Telemetry\Info $telemetryInfo;
  38160. /**
  38161. * @psalm-var class-string
  38162. */
  38163. private readonly string $testClassName;
  38164. private readonly Code\ClassMethod $calledMethod;
  38165. private readonly Throwable $throwable;
  38166. /**
  38167. * @psalm-param class-string $testClassName
  38168. */
  38169. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
  38170. {
  38171. $this->telemetryInfo = $telemetryInfo;
  38172. $this->testClassName = $testClassName;
  38173. $this->calledMethod = $calledMethod;
  38174. $this->throwable = $throwable;
  38175. }
  38176. public function telemetryInfo(): Telemetry\Info
  38177. {
  38178. return $this->telemetryInfo;
  38179. }
  38180. /**
  38181. * @psalm-return class-string
  38182. */
  38183. public function testClassName(): string
  38184. {
  38185. return $this->testClassName;
  38186. }
  38187. public function calledMethod(): Code\ClassMethod
  38188. {
  38189. return $this->calledMethod;
  38190. }
  38191. public function throwable(): Throwable
  38192. {
  38193. return $this->throwable;
  38194. }
  38195. public function asString(): string
  38196. {
  38197. $message = $this->throwable->message();
  38198. if (!empty($message)) {
  38199. $message = PHP_EOL . $message;
  38200. }
  38201. return sprintf('Before First Test Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
  38202. }
  38203. }
  38204. <?php
  38205. declare (strict_types=1);
  38206. /*
  38207. * This file is part of PHPUnit.
  38208. *
  38209. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38210. *
  38211. * For the full copyright and license information, please view the LICENSE
  38212. * file that was distributed with this source code.
  38213. */
  38214. namespace PHPUnit\Event\Test;
  38215. use PHPUnit\Event\Subscriber;
  38216. /**
  38217. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38218. */
  38219. interface BeforeFirstTestMethodErroredSubscriber extends Subscriber
  38220. {
  38221. public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodErrored $event): void;
  38222. }
  38223. <?php
  38224. declare (strict_types=1);
  38225. /*
  38226. * This file is part of PHPUnit.
  38227. *
  38228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38229. *
  38230. * For the full copyright and license information, please view the LICENSE
  38231. * file that was distributed with this source code.
  38232. */
  38233. namespace PHPUnit\Event\Test;
  38234. use const PHP_EOL;
  38235. use function sprintf;
  38236. use PHPUnit\Event\Code;
  38237. use PHPUnit\Event\Event;
  38238. use PHPUnit\Event\Telemetry;
  38239. /**
  38240. * @psalm-immutable
  38241. *
  38242. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38243. */
  38244. final class BeforeFirstTestMethodFinished implements Event
  38245. {
  38246. private readonly Telemetry\Info $telemetryInfo;
  38247. /**
  38248. * @psalm-var class-string
  38249. */
  38250. private readonly string $testClassName;
  38251. /**
  38252. * @psalm-var list<Code\ClassMethod>
  38253. */
  38254. private readonly array $calledMethods;
  38255. /**
  38256. * @psalm-param class-string $testClassName
  38257. */
  38258. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  38259. {
  38260. $this->telemetryInfo = $telemetryInfo;
  38261. $this->testClassName = $testClassName;
  38262. $this->calledMethods = $calledMethods;
  38263. }
  38264. public function telemetryInfo(): Telemetry\Info
  38265. {
  38266. return $this->telemetryInfo;
  38267. }
  38268. /**
  38269. * @psalm-return class-string
  38270. */
  38271. public function testClassName(): string
  38272. {
  38273. return $this->testClassName;
  38274. }
  38275. /**
  38276. * @psalm-return list<Code\ClassMethod>
  38277. */
  38278. public function calledMethods(): array
  38279. {
  38280. return $this->calledMethods;
  38281. }
  38282. public function asString(): string
  38283. {
  38284. $buffer = 'Before First Test Method Finished:';
  38285. foreach ($this->calledMethods as $calledMethod) {
  38286. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  38287. }
  38288. return $buffer;
  38289. }
  38290. }
  38291. <?php
  38292. declare (strict_types=1);
  38293. /*
  38294. * This file is part of PHPUnit.
  38295. *
  38296. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38297. *
  38298. * For the full copyright and license information, please view the LICENSE
  38299. * file that was distributed with this source code.
  38300. */
  38301. namespace PHPUnit\Event\Test;
  38302. use PHPUnit\Event\Subscriber;
  38303. /**
  38304. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38305. */
  38306. interface BeforeFirstTestMethodFinishedSubscriber extends Subscriber
  38307. {
  38308. public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodFinished $event): void;
  38309. }
  38310. <?php
  38311. declare (strict_types=1);
  38312. /*
  38313. * This file is part of PHPUnit.
  38314. *
  38315. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38316. *
  38317. * For the full copyright and license information, please view the LICENSE
  38318. * file that was distributed with this source code.
  38319. */
  38320. namespace PHPUnit\Event\Test;
  38321. use function sprintf;
  38322. use PHPUnit\Event\Code;
  38323. use PHPUnit\Event\Event;
  38324. use PHPUnit\Event\Telemetry;
  38325. /**
  38326. * @psalm-immutable
  38327. *
  38328. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38329. */
  38330. final class BeforeTestMethodCalled implements Event
  38331. {
  38332. private readonly Telemetry\Info $telemetryInfo;
  38333. /**
  38334. * @psalm-var class-string
  38335. */
  38336. private readonly string $testClassName;
  38337. private readonly Code\ClassMethod $calledMethod;
  38338. /**
  38339. * @psalm-param class-string $testClassName
  38340. */
  38341. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  38342. {
  38343. $this->telemetryInfo = $telemetryInfo;
  38344. $this->testClassName = $testClassName;
  38345. $this->calledMethod = $calledMethod;
  38346. }
  38347. public function telemetryInfo(): Telemetry\Info
  38348. {
  38349. return $this->telemetryInfo;
  38350. }
  38351. /**
  38352. * @psalm-return class-string
  38353. */
  38354. public function testClassName(): string
  38355. {
  38356. return $this->testClassName;
  38357. }
  38358. public function calledMethod(): Code\ClassMethod
  38359. {
  38360. return $this->calledMethod;
  38361. }
  38362. public function asString(): string
  38363. {
  38364. return sprintf('Before Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  38365. }
  38366. }
  38367. <?php
  38368. declare (strict_types=1);
  38369. /*
  38370. * This file is part of PHPUnit.
  38371. *
  38372. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38373. *
  38374. * For the full copyright and license information, please view the LICENSE
  38375. * file that was distributed with this source code.
  38376. */
  38377. namespace PHPUnit\Event\Test;
  38378. use PHPUnit\Event\Subscriber;
  38379. /**
  38380. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38381. */
  38382. interface BeforeTestMethodCalledSubscriber extends Subscriber
  38383. {
  38384. public function notify(\PHPUnit\Event\Test\BeforeTestMethodCalled $event): void;
  38385. }
  38386. <?php
  38387. declare (strict_types=1);
  38388. /*
  38389. * This file is part of PHPUnit.
  38390. *
  38391. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38392. *
  38393. * For the full copyright and license information, please view the LICENSE
  38394. * file that was distributed with this source code.
  38395. */
  38396. namespace PHPUnit\Event\Test;
  38397. use const PHP_EOL;
  38398. use function sprintf;
  38399. use PHPUnit\Event\Code;
  38400. use PHPUnit\Event\Event;
  38401. use PHPUnit\Event\Telemetry;
  38402. /**
  38403. * @psalm-immutable
  38404. *
  38405. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38406. */
  38407. final class BeforeTestMethodFinished implements Event
  38408. {
  38409. private readonly Telemetry\Info $telemetryInfo;
  38410. /**
  38411. * @psalm-var class-string
  38412. */
  38413. private readonly string $testClassName;
  38414. /**
  38415. * @psalm-var list<Code\ClassMethod>
  38416. */
  38417. private readonly array $calledMethods;
  38418. /**
  38419. * @psalm-param class-string $testClassName
  38420. */
  38421. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  38422. {
  38423. $this->telemetryInfo = $telemetryInfo;
  38424. $this->testClassName = $testClassName;
  38425. $this->calledMethods = $calledMethods;
  38426. }
  38427. public function telemetryInfo(): Telemetry\Info
  38428. {
  38429. return $this->telemetryInfo;
  38430. }
  38431. /**
  38432. * @psalm-return class-string
  38433. */
  38434. public function testClassName(): string
  38435. {
  38436. return $this->testClassName;
  38437. }
  38438. /**
  38439. * @psalm-return list<Code\ClassMethod>
  38440. */
  38441. public function calledMethods(): array
  38442. {
  38443. return $this->calledMethods;
  38444. }
  38445. public function asString(): string
  38446. {
  38447. $buffer = 'Before Test Method Finished:';
  38448. foreach ($this->calledMethods as $calledMethod) {
  38449. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  38450. }
  38451. return $buffer;
  38452. }
  38453. }
  38454. <?php
  38455. declare (strict_types=1);
  38456. /*
  38457. * This file is part of PHPUnit.
  38458. *
  38459. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38460. *
  38461. * For the full copyright and license information, please view the LICENSE
  38462. * file that was distributed with this source code.
  38463. */
  38464. namespace PHPUnit\Event\Test;
  38465. use PHPUnit\Event\Subscriber;
  38466. /**
  38467. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38468. */
  38469. interface BeforeTestMethodFinishedSubscriber extends Subscriber
  38470. {
  38471. public function notify(\PHPUnit\Event\Test\BeforeTestMethodFinished $event): void;
  38472. }
  38473. <?php
  38474. declare (strict_types=1);
  38475. /*
  38476. * This file is part of PHPUnit.
  38477. *
  38478. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38479. *
  38480. * For the full copyright and license information, please view the LICENSE
  38481. * file that was distributed with this source code.
  38482. */
  38483. namespace PHPUnit\Event\Test;
  38484. use function sprintf;
  38485. use PHPUnit\Event\Code;
  38486. use PHPUnit\Event\Event;
  38487. use PHPUnit\Event\Telemetry;
  38488. /**
  38489. * @psalm-immutable
  38490. *
  38491. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38492. */
  38493. final class PostConditionCalled implements Event
  38494. {
  38495. private readonly Telemetry\Info $telemetryInfo;
  38496. /**
  38497. * @psalm-var class-string
  38498. */
  38499. private readonly string $testClassName;
  38500. private readonly Code\ClassMethod $calledMethod;
  38501. /**
  38502. * @psalm-param class-string $testClassName
  38503. */
  38504. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  38505. {
  38506. $this->telemetryInfo = $telemetryInfo;
  38507. $this->testClassName = $testClassName;
  38508. $this->calledMethod = $calledMethod;
  38509. }
  38510. public function telemetryInfo(): Telemetry\Info
  38511. {
  38512. return $this->telemetryInfo;
  38513. }
  38514. /**
  38515. * @psalm-return class-string
  38516. */
  38517. public function testClassName(): string
  38518. {
  38519. return $this->testClassName;
  38520. }
  38521. public function calledMethod(): Code\ClassMethod
  38522. {
  38523. return $this->calledMethod;
  38524. }
  38525. public function asString(): string
  38526. {
  38527. return sprintf('Post Condition Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  38528. }
  38529. }
  38530. <?php
  38531. declare (strict_types=1);
  38532. /*
  38533. * This file is part of PHPUnit.
  38534. *
  38535. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38536. *
  38537. * For the full copyright and license information, please view the LICENSE
  38538. * file that was distributed with this source code.
  38539. */
  38540. namespace PHPUnit\Event\Test;
  38541. use PHPUnit\Event\Subscriber;
  38542. /**
  38543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38544. */
  38545. interface PostConditionCalledSubscriber extends Subscriber
  38546. {
  38547. public function notify(\PHPUnit\Event\Test\PostConditionCalled $event): void;
  38548. }
  38549. <?php
  38550. declare (strict_types=1);
  38551. /*
  38552. * This file is part of PHPUnit.
  38553. *
  38554. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38555. *
  38556. * For the full copyright and license information, please view the LICENSE
  38557. * file that was distributed with this source code.
  38558. */
  38559. namespace PHPUnit\Event\Test;
  38560. use const PHP_EOL;
  38561. use function sprintf;
  38562. use PHPUnit\Event\Code;
  38563. use PHPUnit\Event\Event;
  38564. use PHPUnit\Event\Telemetry;
  38565. /**
  38566. * @psalm-immutable
  38567. *
  38568. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38569. */
  38570. final class PostConditionFinished implements Event
  38571. {
  38572. private readonly Telemetry\Info $telemetryInfo;
  38573. /**
  38574. * @psalm-var class-string
  38575. */
  38576. private readonly string $testClassName;
  38577. /**
  38578. * @psalm-var list<Code\ClassMethod>
  38579. */
  38580. private readonly array $calledMethods;
  38581. /**
  38582. * @psalm-param class-string $testClassName
  38583. */
  38584. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  38585. {
  38586. $this->telemetryInfo = $telemetryInfo;
  38587. $this->testClassName = $testClassName;
  38588. $this->calledMethods = $calledMethods;
  38589. }
  38590. public function telemetryInfo(): Telemetry\Info
  38591. {
  38592. return $this->telemetryInfo;
  38593. }
  38594. /**
  38595. * @psalm-return class-string
  38596. */
  38597. public function testClassName(): string
  38598. {
  38599. return $this->testClassName;
  38600. }
  38601. /**
  38602. * @psalm-return list<Code\ClassMethod>
  38603. */
  38604. public function calledMethods(): array
  38605. {
  38606. return $this->calledMethods;
  38607. }
  38608. public function asString(): string
  38609. {
  38610. $buffer = 'Post Condition Method Finished:';
  38611. foreach ($this->calledMethods as $calledMethod) {
  38612. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  38613. }
  38614. return $buffer;
  38615. }
  38616. }
  38617. <?php
  38618. declare (strict_types=1);
  38619. /*
  38620. * This file is part of PHPUnit.
  38621. *
  38622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38623. *
  38624. * For the full copyright and license information, please view the LICENSE
  38625. * file that was distributed with this source code.
  38626. */
  38627. namespace PHPUnit\Event\Test;
  38628. use PHPUnit\Event\Subscriber;
  38629. /**
  38630. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38631. */
  38632. interface PostConditionFinishedSubscriber extends Subscriber
  38633. {
  38634. public function notify(\PHPUnit\Event\Test\PostConditionFinished $event): void;
  38635. }
  38636. <?php
  38637. declare (strict_types=1);
  38638. /*
  38639. * This file is part of PHPUnit.
  38640. *
  38641. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38642. *
  38643. * For the full copyright and license information, please view the LICENSE
  38644. * file that was distributed with this source code.
  38645. */
  38646. namespace PHPUnit\Event\Test;
  38647. use function sprintf;
  38648. use PHPUnit\Event\Code;
  38649. use PHPUnit\Event\Event;
  38650. use PHPUnit\Event\Telemetry;
  38651. /**
  38652. * @psalm-immutable
  38653. *
  38654. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38655. */
  38656. final class PreConditionCalled implements Event
  38657. {
  38658. private readonly Telemetry\Info $telemetryInfo;
  38659. /**
  38660. * @psalm-var class-string
  38661. */
  38662. private readonly string $testClassName;
  38663. private readonly Code\ClassMethod $calledMethod;
  38664. /**
  38665. * @psalm-param class-string $testClassName
  38666. */
  38667. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
  38668. {
  38669. $this->telemetryInfo = $telemetryInfo;
  38670. $this->testClassName = $testClassName;
  38671. $this->calledMethod = $calledMethod;
  38672. }
  38673. public function telemetryInfo(): Telemetry\Info
  38674. {
  38675. return $this->telemetryInfo;
  38676. }
  38677. /**
  38678. * @psalm-return class-string
  38679. */
  38680. public function testClassName(): string
  38681. {
  38682. return $this->testClassName;
  38683. }
  38684. public function calledMethod(): Code\ClassMethod
  38685. {
  38686. return $this->calledMethod;
  38687. }
  38688. public function asString(): string
  38689. {
  38690. return sprintf('Pre Condition Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
  38691. }
  38692. }
  38693. <?php
  38694. declare (strict_types=1);
  38695. /*
  38696. * This file is part of PHPUnit.
  38697. *
  38698. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38699. *
  38700. * For the full copyright and license information, please view the LICENSE
  38701. * file that was distributed with this source code.
  38702. */
  38703. namespace PHPUnit\Event\Test;
  38704. use PHPUnit\Event\Subscriber;
  38705. /**
  38706. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38707. */
  38708. interface PreConditionCalledSubscriber extends Subscriber
  38709. {
  38710. public function notify(\PHPUnit\Event\Test\PreConditionCalled $event): void;
  38711. }
  38712. <?php
  38713. declare (strict_types=1);
  38714. /*
  38715. * This file is part of PHPUnit.
  38716. *
  38717. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38718. *
  38719. * For the full copyright and license information, please view the LICENSE
  38720. * file that was distributed with this source code.
  38721. */
  38722. namespace PHPUnit\Event\Test;
  38723. use const PHP_EOL;
  38724. use function sprintf;
  38725. use PHPUnit\Event\Code;
  38726. use PHPUnit\Event\Event;
  38727. use PHPUnit\Event\Telemetry;
  38728. /**
  38729. * @psalm-immutable
  38730. *
  38731. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38732. */
  38733. final class PreConditionFinished implements Event
  38734. {
  38735. private readonly Telemetry\Info $telemetryInfo;
  38736. /**
  38737. * @psalm-var class-string
  38738. */
  38739. private readonly string $testClassName;
  38740. /**
  38741. * @psalm-var list<Code\ClassMethod>
  38742. */
  38743. private readonly array $calledMethods;
  38744. /**
  38745. * @psalm-param class-string $testClassName
  38746. */
  38747. public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
  38748. {
  38749. $this->telemetryInfo = $telemetryInfo;
  38750. $this->testClassName = $testClassName;
  38751. $this->calledMethods = $calledMethods;
  38752. }
  38753. public function telemetryInfo(): Telemetry\Info
  38754. {
  38755. return $this->telemetryInfo;
  38756. }
  38757. /**
  38758. * @psalm-return class-string
  38759. */
  38760. public function testClassName(): string
  38761. {
  38762. return $this->testClassName;
  38763. }
  38764. /**
  38765. * @psalm-return list<Code\ClassMethod>
  38766. */
  38767. public function calledMethods(): array
  38768. {
  38769. return $this->calledMethods;
  38770. }
  38771. public function asString(): string
  38772. {
  38773. $buffer = 'Pre Condition Method Finished:';
  38774. foreach ($this->calledMethods as $calledMethod) {
  38775. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  38776. }
  38777. return $buffer;
  38778. }
  38779. }
  38780. <?php
  38781. declare (strict_types=1);
  38782. /*
  38783. * This file is part of PHPUnit.
  38784. *
  38785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38786. *
  38787. * For the full copyright and license information, please view the LICENSE
  38788. * file that was distributed with this source code.
  38789. */
  38790. namespace PHPUnit\Event\Test;
  38791. use PHPUnit\Event\Subscriber;
  38792. /**
  38793. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38794. */
  38795. interface PreConditionFinishedSubscriber extends Subscriber
  38796. {
  38797. public function notify(\PHPUnit\Event\Test\PreConditionFinished $event): void;
  38798. }
  38799. <?php
  38800. declare (strict_types=1);
  38801. /*
  38802. * This file is part of PHPUnit.
  38803. *
  38804. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38805. *
  38806. * For the full copyright and license information, please view the LICENSE
  38807. * file that was distributed with this source code.
  38808. */
  38809. namespace PHPUnit\Event\Test;
  38810. use const PHP_EOL;
  38811. use function sprintf;
  38812. use PHPUnit\Event\Code;
  38813. use PHPUnit\Event\Event;
  38814. use PHPUnit\Event\Telemetry;
  38815. /**
  38816. * @psalm-immutable
  38817. *
  38818. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38819. */
  38820. final class ConsideredRisky implements Event
  38821. {
  38822. private readonly Telemetry\Info $telemetryInfo;
  38823. private readonly Code\Test $test;
  38824. /**
  38825. * @psalm-var non-empty-string
  38826. */
  38827. private readonly string $message;
  38828. /**
  38829. * @psalm-param non-empty-string $message
  38830. */
  38831. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message)
  38832. {
  38833. $this->telemetryInfo = $telemetryInfo;
  38834. $this->test = $test;
  38835. $this->message = $message;
  38836. }
  38837. public function telemetryInfo(): Telemetry\Info
  38838. {
  38839. return $this->telemetryInfo;
  38840. }
  38841. public function test(): Code\Test
  38842. {
  38843. return $this->test;
  38844. }
  38845. /**
  38846. * @psalm-return non-empty-string
  38847. */
  38848. public function message(): string
  38849. {
  38850. return $this->message;
  38851. }
  38852. public function asString(): string
  38853. {
  38854. return sprintf('Test Considered Risky (%s)%s%s', $this->test->id(), PHP_EOL, $this->message);
  38855. }
  38856. }
  38857. <?php
  38858. declare (strict_types=1);
  38859. /*
  38860. * This file is part of PHPUnit.
  38861. *
  38862. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38863. *
  38864. * For the full copyright and license information, please view the LICENSE
  38865. * file that was distributed with this source code.
  38866. */
  38867. namespace PHPUnit\Event\Test;
  38868. use PHPUnit\Event\Subscriber;
  38869. /**
  38870. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38871. */
  38872. interface ConsideredRiskySubscriber extends Subscriber
  38873. {
  38874. public function notify(\PHPUnit\Event\Test\ConsideredRisky $event): void;
  38875. }
  38876. <?php
  38877. declare (strict_types=1);
  38878. /*
  38879. * This file is part of PHPUnit.
  38880. *
  38881. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38882. *
  38883. * For the full copyright and license information, please view the LICENSE
  38884. * file that was distributed with this source code.
  38885. */
  38886. namespace PHPUnit\Event\Test;
  38887. use const PHP_EOL;
  38888. use function sprintf;
  38889. use PHPUnit\Event\Code\Test;
  38890. use PHPUnit\Event\Event;
  38891. use PHPUnit\Event\Telemetry;
  38892. /**
  38893. * @psalm-immutable
  38894. *
  38895. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  38896. */
  38897. final class DeprecationTriggered implements Event
  38898. {
  38899. private readonly Telemetry\Info $telemetryInfo;
  38900. private readonly Test $test;
  38901. /**
  38902. * @psalm-var non-empty-string
  38903. */
  38904. private readonly string $message;
  38905. /**
  38906. * @psalm-var non-empty-string
  38907. */
  38908. private readonly string $file;
  38909. /**
  38910. * @psalm-var positive-int
  38911. */
  38912. private readonly int $line;
  38913. private readonly bool $suppressed;
  38914. private readonly bool $ignoredByBaseline;
  38915. private readonly bool $ignoredByTest;
  38916. /**
  38917. * @psalm-param non-empty-string $message
  38918. * @psalm-param non-empty-string $file
  38919. * @psalm-param positive-int $line
  38920. */
  38921. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest)
  38922. {
  38923. $this->telemetryInfo = $telemetryInfo;
  38924. $this->test = $test;
  38925. $this->message = $message;
  38926. $this->file = $file;
  38927. $this->line = $line;
  38928. $this->suppressed = $suppressed;
  38929. $this->ignoredByBaseline = $ignoredByBaseline;
  38930. $this->ignoredByTest = $ignoredByTest;
  38931. }
  38932. public function telemetryInfo(): Telemetry\Info
  38933. {
  38934. return $this->telemetryInfo;
  38935. }
  38936. public function test(): Test
  38937. {
  38938. return $this->test;
  38939. }
  38940. /**
  38941. * @psalm-return non-empty-string
  38942. */
  38943. public function message(): string
  38944. {
  38945. return $this->message;
  38946. }
  38947. /**
  38948. * @psalm-return non-empty-string
  38949. */
  38950. public function file(): string
  38951. {
  38952. return $this->file;
  38953. }
  38954. /**
  38955. * @psalm-return positive-int
  38956. */
  38957. public function line(): int
  38958. {
  38959. return $this->line;
  38960. }
  38961. public function wasSuppressed(): bool
  38962. {
  38963. return $this->suppressed;
  38964. }
  38965. public function ignoredByBaseline(): bool
  38966. {
  38967. return $this->ignoredByBaseline;
  38968. }
  38969. public function ignoredByTest(): bool
  38970. {
  38971. return $this->ignoredByTest;
  38972. }
  38973. public function asString(): string
  38974. {
  38975. $message = $this->message;
  38976. if (!empty($message)) {
  38977. $message = PHP_EOL . $message;
  38978. }
  38979. $status = '';
  38980. if ($this->ignoredByTest) {
  38981. $status = 'Test-Ignored ';
  38982. } elseif ($this->ignoredByBaseline) {
  38983. $status = 'Baseline-Ignored ';
  38984. } elseif ($this->suppressed) {
  38985. $status = 'Suppressed ';
  38986. }
  38987. return sprintf('Test Triggered %sDeprecation (%s)%s', $status, $this->test->id(), $message);
  38988. }
  38989. }
  38990. <?php
  38991. declare (strict_types=1);
  38992. /*
  38993. * This file is part of PHPUnit.
  38994. *
  38995. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38996. *
  38997. * For the full copyright and license information, please view the LICENSE
  38998. * file that was distributed with this source code.
  38999. */
  39000. namespace PHPUnit\Event\Test;
  39001. use PHPUnit\Event\Subscriber;
  39002. /**
  39003. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39004. */
  39005. interface DeprecationTriggeredSubscriber extends Subscriber
  39006. {
  39007. public function notify(\PHPUnit\Event\Test\DeprecationTriggered $event): void;
  39008. }
  39009. <?php
  39010. declare (strict_types=1);
  39011. /*
  39012. * This file is part of PHPUnit.
  39013. *
  39014. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39015. *
  39016. * For the full copyright and license information, please view the LICENSE
  39017. * file that was distributed with this source code.
  39018. */
  39019. namespace PHPUnit\Event\Test;
  39020. use const PHP_EOL;
  39021. use function sprintf;
  39022. use PHPUnit\Event\Code\Test;
  39023. use PHPUnit\Event\Event;
  39024. use PHPUnit\Event\Telemetry;
  39025. /**
  39026. * @psalm-immutable
  39027. *
  39028. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39029. */
  39030. final class ErrorTriggered implements Event
  39031. {
  39032. private readonly Telemetry\Info $telemetryInfo;
  39033. private readonly Test $test;
  39034. /**
  39035. * @psalm-var non-empty-string
  39036. */
  39037. private readonly string $message;
  39038. /**
  39039. * @psalm-var non-empty-string
  39040. */
  39041. private readonly string $file;
  39042. /**
  39043. * @psalm-var positive-int
  39044. */
  39045. private readonly int $line;
  39046. private readonly bool $suppressed;
  39047. /**
  39048. * @psalm-param non-empty-string $message
  39049. * @psalm-param non-empty-string $file
  39050. * @psalm-param positive-int $line
  39051. */
  39052. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed)
  39053. {
  39054. $this->telemetryInfo = $telemetryInfo;
  39055. $this->test = $test;
  39056. $this->message = $message;
  39057. $this->file = $file;
  39058. $this->line = $line;
  39059. $this->suppressed = $suppressed;
  39060. }
  39061. public function telemetryInfo(): Telemetry\Info
  39062. {
  39063. return $this->telemetryInfo;
  39064. }
  39065. public function test(): Test
  39066. {
  39067. return $this->test;
  39068. }
  39069. /**
  39070. * @psalm-return non-empty-string
  39071. */
  39072. public function message(): string
  39073. {
  39074. return $this->message;
  39075. }
  39076. /**
  39077. * @psalm-return non-empty-string
  39078. */
  39079. public function file(): string
  39080. {
  39081. return $this->file;
  39082. }
  39083. /**
  39084. * @psalm-return positive-int
  39085. */
  39086. public function line(): int
  39087. {
  39088. return $this->line;
  39089. }
  39090. public function wasSuppressed(): bool
  39091. {
  39092. return $this->suppressed;
  39093. }
  39094. public function asString(): string
  39095. {
  39096. $message = $this->message;
  39097. if (!empty($message)) {
  39098. $message = PHP_EOL . $message;
  39099. }
  39100. return sprintf('Test Triggered %sError (%s)%s', $this->wasSuppressed() ? 'Suppressed ' : '', $this->test->id(), $message);
  39101. }
  39102. }
  39103. <?php
  39104. declare (strict_types=1);
  39105. /*
  39106. * This file is part of PHPUnit.
  39107. *
  39108. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39109. *
  39110. * For the full copyright and license information, please view the LICENSE
  39111. * file that was distributed with this source code.
  39112. */
  39113. namespace PHPUnit\Event\Test;
  39114. use PHPUnit\Event\Subscriber;
  39115. /**
  39116. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39117. */
  39118. interface ErrorTriggeredSubscriber extends Subscriber
  39119. {
  39120. public function notify(\PHPUnit\Event\Test\ErrorTriggered $event): void;
  39121. }
  39122. <?php
  39123. declare (strict_types=1);
  39124. /*
  39125. * This file is part of PHPUnit.
  39126. *
  39127. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39128. *
  39129. * For the full copyright and license information, please view the LICENSE
  39130. * file that was distributed with this source code.
  39131. */
  39132. namespace PHPUnit\Event\Test;
  39133. use const PHP_EOL;
  39134. use function sprintf;
  39135. use PHPUnit\Event\Code\Test;
  39136. use PHPUnit\Event\Event;
  39137. use PHPUnit\Event\Telemetry;
  39138. /**
  39139. * @psalm-immutable
  39140. *
  39141. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39142. */
  39143. final class NoticeTriggered implements Event
  39144. {
  39145. private readonly Telemetry\Info $telemetryInfo;
  39146. private readonly Test $test;
  39147. /**
  39148. * @psalm-var non-empty-string
  39149. */
  39150. private readonly string $message;
  39151. /**
  39152. * @psalm-var non-empty-string
  39153. */
  39154. private readonly string $file;
  39155. /**
  39156. * @psalm-var positive-int
  39157. */
  39158. private readonly int $line;
  39159. private readonly bool $suppressed;
  39160. private readonly bool $ignoredByBaseline;
  39161. /**
  39162. * @psalm-param non-empty-string $message
  39163. * @psalm-param non-empty-string $file
  39164. * @psalm-param positive-int $line
  39165. */
  39166. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
  39167. {
  39168. $this->telemetryInfo = $telemetryInfo;
  39169. $this->test = $test;
  39170. $this->message = $message;
  39171. $this->file = $file;
  39172. $this->line = $line;
  39173. $this->suppressed = $suppressed;
  39174. $this->ignoredByBaseline = $ignoredByBaseline;
  39175. }
  39176. public function telemetryInfo(): Telemetry\Info
  39177. {
  39178. return $this->telemetryInfo;
  39179. }
  39180. public function test(): Test
  39181. {
  39182. return $this->test;
  39183. }
  39184. /**
  39185. * @psalm-return non-empty-string
  39186. */
  39187. public function message(): string
  39188. {
  39189. return $this->message;
  39190. }
  39191. /**
  39192. * @psalm-return non-empty-string
  39193. */
  39194. public function file(): string
  39195. {
  39196. return $this->file;
  39197. }
  39198. /**
  39199. * @psalm-return positive-int
  39200. */
  39201. public function line(): int
  39202. {
  39203. return $this->line;
  39204. }
  39205. public function wasSuppressed(): bool
  39206. {
  39207. return $this->suppressed;
  39208. }
  39209. public function ignoredByBaseline(): bool
  39210. {
  39211. return $this->ignoredByBaseline;
  39212. }
  39213. public function asString(): string
  39214. {
  39215. $message = $this->message;
  39216. if (!empty($message)) {
  39217. $message = PHP_EOL . $message;
  39218. }
  39219. $status = '';
  39220. if ($this->ignoredByBaseline) {
  39221. $status = 'Baseline-Ignored ';
  39222. } elseif ($this->suppressed) {
  39223. $status = 'Suppressed ';
  39224. }
  39225. return sprintf('Test Triggered %sNotice (%s)%s', $status, $this->test->id(), $message);
  39226. }
  39227. }
  39228. <?php
  39229. declare (strict_types=1);
  39230. /*
  39231. * This file is part of PHPUnit.
  39232. *
  39233. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39234. *
  39235. * For the full copyright and license information, please view the LICENSE
  39236. * file that was distributed with this source code.
  39237. */
  39238. namespace PHPUnit\Event\Test;
  39239. use PHPUnit\Event\Subscriber;
  39240. /**
  39241. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39242. */
  39243. interface NoticeTriggeredSubscriber extends Subscriber
  39244. {
  39245. public function notify(\PHPUnit\Event\Test\NoticeTriggered $event): void;
  39246. }
  39247. <?php
  39248. declare (strict_types=1);
  39249. /*
  39250. * This file is part of PHPUnit.
  39251. *
  39252. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39253. *
  39254. * For the full copyright and license information, please view the LICENSE
  39255. * file that was distributed with this source code.
  39256. */
  39257. namespace PHPUnit\Event\Test;
  39258. use const PHP_EOL;
  39259. use function sprintf;
  39260. use PHPUnit\Event\Code\Test;
  39261. use PHPUnit\Event\Event;
  39262. use PHPUnit\Event\Telemetry;
  39263. /**
  39264. * @psalm-immutable
  39265. *
  39266. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39267. */
  39268. final class PhpDeprecationTriggered implements Event
  39269. {
  39270. private readonly Telemetry\Info $telemetryInfo;
  39271. private readonly Test $test;
  39272. /**
  39273. * @psalm-var non-empty-string
  39274. */
  39275. private readonly string $message;
  39276. /**
  39277. * @psalm-var non-empty-string
  39278. */
  39279. private readonly string $file;
  39280. /**
  39281. * @psalm-var positive-int
  39282. */
  39283. private readonly int $line;
  39284. private readonly bool $suppressed;
  39285. private readonly bool $ignoredByBaseline;
  39286. private readonly bool $ignoredByTest;
  39287. /**
  39288. * @psalm-param non-empty-string $message
  39289. * @psalm-param non-empty-string $file
  39290. * @psalm-param positive-int $line
  39291. */
  39292. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest)
  39293. {
  39294. $this->telemetryInfo = $telemetryInfo;
  39295. $this->test = $test;
  39296. $this->message = $message;
  39297. $this->file = $file;
  39298. $this->line = $line;
  39299. $this->suppressed = $suppressed;
  39300. $this->ignoredByBaseline = $ignoredByBaseline;
  39301. $this->ignoredByTest = $ignoredByTest;
  39302. }
  39303. public function telemetryInfo(): Telemetry\Info
  39304. {
  39305. return $this->telemetryInfo;
  39306. }
  39307. public function test(): Test
  39308. {
  39309. return $this->test;
  39310. }
  39311. /**
  39312. * @psalm-return non-empty-string
  39313. */
  39314. public function message(): string
  39315. {
  39316. return $this->message;
  39317. }
  39318. /**
  39319. * @psalm-return non-empty-string
  39320. */
  39321. public function file(): string
  39322. {
  39323. return $this->file;
  39324. }
  39325. /**
  39326. * @psalm-return positive-int
  39327. */
  39328. public function line(): int
  39329. {
  39330. return $this->line;
  39331. }
  39332. public function wasSuppressed(): bool
  39333. {
  39334. return $this->suppressed;
  39335. }
  39336. public function ignoredByBaseline(): bool
  39337. {
  39338. return $this->ignoredByBaseline;
  39339. }
  39340. public function ignoredByTest(): bool
  39341. {
  39342. return $this->ignoredByTest;
  39343. }
  39344. public function asString(): string
  39345. {
  39346. $message = $this->message;
  39347. if (!empty($message)) {
  39348. $message = PHP_EOL . $message;
  39349. }
  39350. $status = '';
  39351. if ($this->ignoredByTest) {
  39352. $status = 'Test-Ignored ';
  39353. } elseif ($this->ignoredByBaseline) {
  39354. $status = 'Baseline-Ignored ';
  39355. } elseif ($this->suppressed) {
  39356. $status = 'Suppressed ';
  39357. }
  39358. return sprintf('Test Triggered %sPHP Deprecation (%s)%s', $status, $this->test->id(), $message);
  39359. }
  39360. }
  39361. <?php
  39362. declare (strict_types=1);
  39363. /*
  39364. * This file is part of PHPUnit.
  39365. *
  39366. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39367. *
  39368. * For the full copyright and license information, please view the LICENSE
  39369. * file that was distributed with this source code.
  39370. */
  39371. namespace PHPUnit\Event\Test;
  39372. use PHPUnit\Event\Subscriber;
  39373. /**
  39374. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39375. */
  39376. interface PhpDeprecationTriggeredSubscriber extends Subscriber
  39377. {
  39378. public function notify(\PHPUnit\Event\Test\PhpDeprecationTriggered $event): void;
  39379. }
  39380. <?php
  39381. declare (strict_types=1);
  39382. /*
  39383. * This file is part of PHPUnit.
  39384. *
  39385. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39386. *
  39387. * For the full copyright and license information, please view the LICENSE
  39388. * file that was distributed with this source code.
  39389. */
  39390. namespace PHPUnit\Event\Test;
  39391. use const PHP_EOL;
  39392. use function sprintf;
  39393. use PHPUnit\Event\Code\Test;
  39394. use PHPUnit\Event\Event;
  39395. use PHPUnit\Event\Telemetry;
  39396. /**
  39397. * @psalm-immutable
  39398. *
  39399. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39400. */
  39401. final class PhpNoticeTriggered implements Event
  39402. {
  39403. private readonly Telemetry\Info $telemetryInfo;
  39404. private readonly Test $test;
  39405. /**
  39406. * @psalm-var non-empty-string
  39407. */
  39408. private readonly string $message;
  39409. /**
  39410. * @psalm-var non-empty-string
  39411. */
  39412. private readonly string $file;
  39413. /**
  39414. * @psalm-var positive-int
  39415. */
  39416. private readonly int $line;
  39417. private readonly bool $suppressed;
  39418. private readonly bool $ignoredByBaseline;
  39419. /**
  39420. * @psalm-param non-empty-string $message
  39421. * @psalm-param non-empty-string $file
  39422. * @psalm-param positive-int $line
  39423. */
  39424. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
  39425. {
  39426. $this->telemetryInfo = $telemetryInfo;
  39427. $this->test = $test;
  39428. $this->message = $message;
  39429. $this->file = $file;
  39430. $this->line = $line;
  39431. $this->suppressed = $suppressed;
  39432. $this->ignoredByBaseline = $ignoredByBaseline;
  39433. }
  39434. public function telemetryInfo(): Telemetry\Info
  39435. {
  39436. return $this->telemetryInfo;
  39437. }
  39438. public function test(): Test
  39439. {
  39440. return $this->test;
  39441. }
  39442. /**
  39443. * @psalm-return non-empty-string
  39444. */
  39445. public function message(): string
  39446. {
  39447. return $this->message;
  39448. }
  39449. /**
  39450. * @psalm-return non-empty-string
  39451. */
  39452. public function file(): string
  39453. {
  39454. return $this->file;
  39455. }
  39456. /**
  39457. * @psalm-return positive-int
  39458. */
  39459. public function line(): int
  39460. {
  39461. return $this->line;
  39462. }
  39463. public function wasSuppressed(): bool
  39464. {
  39465. return $this->suppressed;
  39466. }
  39467. public function ignoredByBaseline(): bool
  39468. {
  39469. return $this->ignoredByBaseline;
  39470. }
  39471. public function asString(): string
  39472. {
  39473. $message = $this->message;
  39474. if (!empty($message)) {
  39475. $message = PHP_EOL . $message;
  39476. }
  39477. $status = '';
  39478. if ($this->ignoredByBaseline) {
  39479. $status = 'Baseline-Ignored ';
  39480. } elseif ($this->suppressed) {
  39481. $status = 'Suppressed ';
  39482. }
  39483. return sprintf('Test Triggered %sPHP Notice (%s)%s', $status, $this->test->id(), $message);
  39484. }
  39485. }
  39486. <?php
  39487. declare (strict_types=1);
  39488. /*
  39489. * This file is part of PHPUnit.
  39490. *
  39491. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39492. *
  39493. * For the full copyright and license information, please view the LICENSE
  39494. * file that was distributed with this source code.
  39495. */
  39496. namespace PHPUnit\Event\Test;
  39497. use PHPUnit\Event\Subscriber;
  39498. /**
  39499. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39500. */
  39501. interface PhpNoticeTriggeredSubscriber extends Subscriber
  39502. {
  39503. public function notify(\PHPUnit\Event\Test\PhpNoticeTriggered $event): void;
  39504. }
  39505. <?php
  39506. declare (strict_types=1);
  39507. /*
  39508. * This file is part of PHPUnit.
  39509. *
  39510. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39511. *
  39512. * For the full copyright and license information, please view the LICENSE
  39513. * file that was distributed with this source code.
  39514. */
  39515. namespace PHPUnit\Event\Test;
  39516. use const PHP_EOL;
  39517. use function sprintf;
  39518. use PHPUnit\Event\Code\Test;
  39519. use PHPUnit\Event\Event;
  39520. use PHPUnit\Event\Telemetry;
  39521. /**
  39522. * @psalm-immutable
  39523. *
  39524. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39525. */
  39526. final class PhpWarningTriggered implements Event
  39527. {
  39528. private readonly Telemetry\Info $telemetryInfo;
  39529. private readonly Test $test;
  39530. /**
  39531. * @psalm-var non-empty-string
  39532. */
  39533. private readonly string $message;
  39534. /**
  39535. * @psalm-var non-empty-string
  39536. */
  39537. private readonly string $file;
  39538. /**
  39539. * @psalm-var positive-int
  39540. */
  39541. private readonly int $line;
  39542. private readonly bool $suppressed;
  39543. private readonly bool $ignoredByBaseline;
  39544. /**
  39545. * @psalm-param non-empty-string $message
  39546. * @psalm-param non-empty-string $file
  39547. * @psalm-param positive-int $line
  39548. */
  39549. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
  39550. {
  39551. $this->telemetryInfo = $telemetryInfo;
  39552. $this->test = $test;
  39553. $this->message = $message;
  39554. $this->file = $file;
  39555. $this->line = $line;
  39556. $this->suppressed = $suppressed;
  39557. $this->ignoredByBaseline = $ignoredByBaseline;
  39558. }
  39559. public function telemetryInfo(): Telemetry\Info
  39560. {
  39561. return $this->telemetryInfo;
  39562. }
  39563. public function test(): Test
  39564. {
  39565. return $this->test;
  39566. }
  39567. /**
  39568. * @psalm-return non-empty-string
  39569. */
  39570. public function message(): string
  39571. {
  39572. return $this->message;
  39573. }
  39574. /**
  39575. * @psalm-return non-empty-string
  39576. */
  39577. public function file(): string
  39578. {
  39579. return $this->file;
  39580. }
  39581. /**
  39582. * @psalm-return positive-int
  39583. */
  39584. public function line(): int
  39585. {
  39586. return $this->line;
  39587. }
  39588. public function wasSuppressed(): bool
  39589. {
  39590. return $this->suppressed;
  39591. }
  39592. public function ignoredByBaseline(): bool
  39593. {
  39594. return $this->ignoredByBaseline;
  39595. }
  39596. public function asString(): string
  39597. {
  39598. $message = $this->message;
  39599. if (!empty($message)) {
  39600. $message = PHP_EOL . $message;
  39601. }
  39602. $status = '';
  39603. if ($this->ignoredByBaseline) {
  39604. $status = 'Baseline-Ignored ';
  39605. } elseif ($this->suppressed) {
  39606. $status = 'Suppressed ';
  39607. }
  39608. return sprintf('Test Triggered %sPHP Warning (%s)%s', $status, $this->test->id(), $message);
  39609. }
  39610. }
  39611. <?php
  39612. declare (strict_types=1);
  39613. /*
  39614. * This file is part of PHPUnit.
  39615. *
  39616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39617. *
  39618. * For the full copyright and license information, please view the LICENSE
  39619. * file that was distributed with this source code.
  39620. */
  39621. namespace PHPUnit\Event\Test;
  39622. use PHPUnit\Event\Subscriber;
  39623. /**
  39624. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39625. */
  39626. interface PhpWarningTriggeredSubscriber extends Subscriber
  39627. {
  39628. public function notify(\PHPUnit\Event\Test\PhpWarningTriggered $event): void;
  39629. }
  39630. <?php
  39631. declare (strict_types=1);
  39632. /*
  39633. * This file is part of PHPUnit.
  39634. *
  39635. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39636. *
  39637. * For the full copyright and license information, please view the LICENSE
  39638. * file that was distributed with this source code.
  39639. */
  39640. namespace PHPUnit\Event\Test;
  39641. use const PHP_EOL;
  39642. use function sprintf;
  39643. use PHPUnit\Event\Code\Test;
  39644. use PHPUnit\Event\Event;
  39645. use PHPUnit\Event\Telemetry;
  39646. /**
  39647. * @psalm-immutable
  39648. *
  39649. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39650. */
  39651. final class PhpunitDeprecationTriggered implements Event
  39652. {
  39653. private readonly Telemetry\Info $telemetryInfo;
  39654. private readonly Test $test;
  39655. /**
  39656. * @psalm-var non-empty-string
  39657. */
  39658. private readonly string $message;
  39659. /**
  39660. * @psalm-param non-empty-string $message
  39661. */
  39662. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
  39663. {
  39664. $this->telemetryInfo = $telemetryInfo;
  39665. $this->test = $test;
  39666. $this->message = $message;
  39667. }
  39668. public function telemetryInfo(): Telemetry\Info
  39669. {
  39670. return $this->telemetryInfo;
  39671. }
  39672. public function test(): Test
  39673. {
  39674. return $this->test;
  39675. }
  39676. /**
  39677. * @psalm-return non-empty-string
  39678. */
  39679. public function message(): string
  39680. {
  39681. return $this->message;
  39682. }
  39683. public function asString(): string
  39684. {
  39685. $message = $this->message;
  39686. if (!empty($message)) {
  39687. $message = PHP_EOL . $message;
  39688. }
  39689. return sprintf('Test Triggered PHPUnit Deprecation (%s)%s', $this->test->id(), $message);
  39690. }
  39691. }
  39692. <?php
  39693. declare (strict_types=1);
  39694. /*
  39695. * This file is part of PHPUnit.
  39696. *
  39697. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39698. *
  39699. * For the full copyright and license information, please view the LICENSE
  39700. * file that was distributed with this source code.
  39701. */
  39702. namespace PHPUnit\Event\Test;
  39703. use PHPUnit\Event\Subscriber;
  39704. /**
  39705. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39706. */
  39707. interface PhpunitDeprecationTriggeredSubscriber extends Subscriber
  39708. {
  39709. public function notify(\PHPUnit\Event\Test\PhpunitDeprecationTriggered $event): void;
  39710. }
  39711. <?php
  39712. declare (strict_types=1);
  39713. /*
  39714. * This file is part of PHPUnit.
  39715. *
  39716. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39717. *
  39718. * For the full copyright and license information, please view the LICENSE
  39719. * file that was distributed with this source code.
  39720. */
  39721. namespace PHPUnit\Event\Test;
  39722. use const PHP_EOL;
  39723. use function sprintf;
  39724. use function trim;
  39725. use PHPUnit\Event\Code\Test;
  39726. use PHPUnit\Event\Event;
  39727. use PHPUnit\Event\Telemetry;
  39728. /**
  39729. * @psalm-immutable
  39730. *
  39731. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39732. */
  39733. final class PhpunitErrorTriggered implements Event
  39734. {
  39735. private readonly Telemetry\Info $telemetryInfo;
  39736. private readonly Test $test;
  39737. /**
  39738. * @psalm-var non-empty-string
  39739. */
  39740. private readonly string $message;
  39741. /**
  39742. * @psalm-param non-empty-string $message
  39743. */
  39744. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
  39745. {
  39746. $this->telemetryInfo = $telemetryInfo;
  39747. $this->test = $test;
  39748. $this->message = $message;
  39749. }
  39750. public function telemetryInfo(): Telemetry\Info
  39751. {
  39752. return $this->telemetryInfo;
  39753. }
  39754. public function test(): Test
  39755. {
  39756. return $this->test;
  39757. }
  39758. /**
  39759. * @psalm-return non-empty-string
  39760. */
  39761. public function message(): string
  39762. {
  39763. return $this->message;
  39764. }
  39765. public function asString(): string
  39766. {
  39767. $message = trim($this->message);
  39768. if (!empty($message)) {
  39769. $message = PHP_EOL . $message;
  39770. }
  39771. return sprintf('Test Triggered PHPUnit Error (%s)%s', $this->test->id(), $message);
  39772. }
  39773. }
  39774. <?php
  39775. declare (strict_types=1);
  39776. /*
  39777. * This file is part of PHPUnit.
  39778. *
  39779. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39780. *
  39781. * For the full copyright and license information, please view the LICENSE
  39782. * file that was distributed with this source code.
  39783. */
  39784. namespace PHPUnit\Event\Test;
  39785. use PHPUnit\Event\Subscriber;
  39786. /**
  39787. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39788. */
  39789. interface PhpunitErrorTriggeredSubscriber extends Subscriber
  39790. {
  39791. public function notify(\PHPUnit\Event\Test\PhpunitErrorTriggered $event): void;
  39792. }
  39793. <?php
  39794. declare (strict_types=1);
  39795. /*
  39796. * This file is part of PHPUnit.
  39797. *
  39798. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39799. *
  39800. * For the full copyright and license information, please view the LICENSE
  39801. * file that was distributed with this source code.
  39802. */
  39803. namespace PHPUnit\Event\Test;
  39804. use const PHP_EOL;
  39805. use function sprintf;
  39806. use PHPUnit\Event\Code\Test;
  39807. use PHPUnit\Event\Event;
  39808. use PHPUnit\Event\Telemetry;
  39809. /**
  39810. * @psalm-immutable
  39811. *
  39812. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39813. */
  39814. final class PhpunitWarningTriggered implements Event
  39815. {
  39816. private readonly Telemetry\Info $telemetryInfo;
  39817. private readonly Test $test;
  39818. /**
  39819. * @psalm-var non-empty-string
  39820. */
  39821. private readonly string $message;
  39822. /**
  39823. * @psalm-param non-empty-string $message
  39824. */
  39825. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
  39826. {
  39827. $this->telemetryInfo = $telemetryInfo;
  39828. $this->test = $test;
  39829. $this->message = $message;
  39830. }
  39831. public function telemetryInfo(): Telemetry\Info
  39832. {
  39833. return $this->telemetryInfo;
  39834. }
  39835. public function test(): Test
  39836. {
  39837. return $this->test;
  39838. }
  39839. /**
  39840. * @psalm-return non-empty-string
  39841. */
  39842. public function message(): string
  39843. {
  39844. return $this->message;
  39845. }
  39846. public function asString(): string
  39847. {
  39848. $message = $this->message;
  39849. if (!empty($message)) {
  39850. $message = PHP_EOL . $message;
  39851. }
  39852. return sprintf('Test Triggered PHPUnit Warning (%s)%s', $this->test->id(), $message);
  39853. }
  39854. }
  39855. <?php
  39856. declare (strict_types=1);
  39857. /*
  39858. * This file is part of PHPUnit.
  39859. *
  39860. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39861. *
  39862. * For the full copyright and license information, please view the LICENSE
  39863. * file that was distributed with this source code.
  39864. */
  39865. namespace PHPUnit\Event\Test;
  39866. use PHPUnit\Event\Subscriber;
  39867. /**
  39868. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39869. */
  39870. interface PhpunitWarningTriggeredSubscriber extends Subscriber
  39871. {
  39872. public function notify(\PHPUnit\Event\Test\PhpunitWarningTriggered $event): void;
  39873. }
  39874. <?php
  39875. declare (strict_types=1);
  39876. /*
  39877. * This file is part of PHPUnit.
  39878. *
  39879. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39880. *
  39881. * For the full copyright and license information, please view the LICENSE
  39882. * file that was distributed with this source code.
  39883. */
  39884. namespace PHPUnit\Event\Test;
  39885. use const PHP_EOL;
  39886. use function sprintf;
  39887. use PHPUnit\Event\Code\Test;
  39888. use PHPUnit\Event\Event;
  39889. use PHPUnit\Event\Telemetry;
  39890. /**
  39891. * @psalm-immutable
  39892. *
  39893. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39894. */
  39895. final class WarningTriggered implements Event
  39896. {
  39897. private readonly Telemetry\Info $telemetryInfo;
  39898. private readonly Test $test;
  39899. /**
  39900. * @psalm-var non-empty-string
  39901. */
  39902. private readonly string $message;
  39903. /**
  39904. * @psalm-var non-empty-string
  39905. */
  39906. private readonly string $file;
  39907. /**
  39908. * @psalm-var positive-int
  39909. */
  39910. private readonly int $line;
  39911. private readonly bool $suppressed;
  39912. private readonly bool $ignoredByBaseline;
  39913. /**
  39914. * @psalm-param non-empty-string $message
  39915. * @psalm-param non-empty-string $file
  39916. * @psalm-param positive-int $line
  39917. */
  39918. public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
  39919. {
  39920. $this->telemetryInfo = $telemetryInfo;
  39921. $this->test = $test;
  39922. $this->message = $message;
  39923. $this->file = $file;
  39924. $this->line = $line;
  39925. $this->suppressed = $suppressed;
  39926. $this->ignoredByBaseline = $ignoredByBaseline;
  39927. }
  39928. public function telemetryInfo(): Telemetry\Info
  39929. {
  39930. return $this->telemetryInfo;
  39931. }
  39932. public function test(): Test
  39933. {
  39934. return $this->test;
  39935. }
  39936. /**
  39937. * @psalm-return non-empty-string
  39938. */
  39939. public function message(): string
  39940. {
  39941. return $this->message;
  39942. }
  39943. /**
  39944. * @psalm-return non-empty-string
  39945. */
  39946. public function file(): string
  39947. {
  39948. return $this->file;
  39949. }
  39950. /**
  39951. * @psalm-return positive-int
  39952. */
  39953. public function line(): int
  39954. {
  39955. return $this->line;
  39956. }
  39957. public function wasSuppressed(): bool
  39958. {
  39959. return $this->suppressed;
  39960. }
  39961. public function ignoredByBaseline(): bool
  39962. {
  39963. return $this->ignoredByBaseline;
  39964. }
  39965. public function asString(): string
  39966. {
  39967. $message = $this->message;
  39968. if (!empty($message)) {
  39969. $message = PHP_EOL . $message;
  39970. }
  39971. $status = '';
  39972. if ($this->ignoredByBaseline) {
  39973. $status = 'Baseline-Ignored ';
  39974. } elseif ($this->suppressed) {
  39975. $status = 'Suppressed ';
  39976. }
  39977. return sprintf('Test Triggered %sWarning (%s)%s', $status, $this->test->id(), $message);
  39978. }
  39979. }
  39980. <?php
  39981. declare (strict_types=1);
  39982. /*
  39983. * This file is part of PHPUnit.
  39984. *
  39985. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39986. *
  39987. * For the full copyright and license information, please view the LICENSE
  39988. * file that was distributed with this source code.
  39989. */
  39990. namespace PHPUnit\Event\Test;
  39991. use PHPUnit\Event\Subscriber;
  39992. /**
  39993. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  39994. */
  39995. interface WarningTriggeredSubscriber extends Subscriber
  39996. {
  39997. public function notify(\PHPUnit\Event\Test\WarningTriggered $event): void;
  39998. }
  39999. <?php
  40000. declare (strict_types=1);
  40001. /*
  40002. * This file is part of PHPUnit.
  40003. *
  40004. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40005. *
  40006. * For the full copyright and license information, please view the LICENSE
  40007. * file that was distributed with this source code.
  40008. */
  40009. namespace PHPUnit\Event\Test;
  40010. use function sprintf;
  40011. use PHPUnit\Event\Code\ClassMethod;
  40012. use PHPUnit\Event\Event;
  40013. use PHPUnit\Event\Telemetry\Info;
  40014. /**
  40015. * @psalm-immutable
  40016. *
  40017. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40018. */
  40019. final class DataProviderMethodCalled implements Event
  40020. {
  40021. private readonly Info $telemetryInfo;
  40022. private readonly ClassMethod $testMethod;
  40023. private readonly ClassMethod $dataProviderMethod;
  40024. public function __construct(Info $telemetryInfo, ClassMethod $testMethod, ClassMethod $dataProviderMethod)
  40025. {
  40026. $this->telemetryInfo = $telemetryInfo;
  40027. $this->testMethod = $testMethod;
  40028. $this->dataProviderMethod = $dataProviderMethod;
  40029. }
  40030. public function telemetryInfo(): Info
  40031. {
  40032. return $this->telemetryInfo;
  40033. }
  40034. public function testMethod(): ClassMethod
  40035. {
  40036. return $this->testMethod;
  40037. }
  40038. public function dataProviderMethod(): ClassMethod
  40039. {
  40040. return $this->dataProviderMethod;
  40041. }
  40042. public function asString(): string
  40043. {
  40044. return sprintf('Data Provider Method Called (%s::%s for test method %s::%s)', $this->dataProviderMethod->className(), $this->dataProviderMethod->methodName(), $this->testMethod->className(), $this->testMethod->methodName());
  40045. }
  40046. }
  40047. <?php
  40048. declare (strict_types=1);
  40049. /*
  40050. * This file is part of PHPUnit.
  40051. *
  40052. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40053. *
  40054. * For the full copyright and license information, please view the LICENSE
  40055. * file that was distributed with this source code.
  40056. */
  40057. namespace PHPUnit\Event\Test;
  40058. use PHPUnit\Event\Subscriber;
  40059. /**
  40060. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40061. */
  40062. interface DataProviderMethodCalledSubscriber extends Subscriber
  40063. {
  40064. public function notify(\PHPUnit\Event\Test\DataProviderMethodCalled $event): void;
  40065. }
  40066. <?php
  40067. declare (strict_types=1);
  40068. /*
  40069. * This file is part of PHPUnit.
  40070. *
  40071. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40072. *
  40073. * For the full copyright and license information, please view the LICENSE
  40074. * file that was distributed with this source code.
  40075. */
  40076. namespace PHPUnit\Event\Test;
  40077. use const PHP_EOL;
  40078. use function sprintf;
  40079. use PHPUnit\Event\Code\ClassMethod;
  40080. use PHPUnit\Event\Event;
  40081. use PHPUnit\Event\Telemetry;
  40082. /**
  40083. * @psalm-immutable
  40084. *
  40085. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40086. */
  40087. final class DataProviderMethodFinished implements Event
  40088. {
  40089. private readonly Telemetry\Info $telemetryInfo;
  40090. private readonly ClassMethod $testMethod;
  40091. /**
  40092. * @psalm-var list<ClassMethod>
  40093. */
  40094. private readonly array $calledMethods;
  40095. public function __construct(Telemetry\Info $telemetryInfo, ClassMethod $testMethod, ClassMethod ...$calledMethods)
  40096. {
  40097. $this->telemetryInfo = $telemetryInfo;
  40098. $this->testMethod = $testMethod;
  40099. $this->calledMethods = $calledMethods;
  40100. }
  40101. public function telemetryInfo(): Telemetry\Info
  40102. {
  40103. return $this->telemetryInfo;
  40104. }
  40105. public function testMethod(): ClassMethod
  40106. {
  40107. return $this->testMethod;
  40108. }
  40109. /**
  40110. * @psalm-return list<ClassMethod>
  40111. */
  40112. public function calledMethods(): array
  40113. {
  40114. return $this->calledMethods;
  40115. }
  40116. public function asString(): string
  40117. {
  40118. $buffer = sprintf('Data Provider Method Finished for %s::%s:', $this->testMethod->className(), $this->testMethod->methodName());
  40119. foreach ($this->calledMethods as $calledMethod) {
  40120. $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
  40121. }
  40122. return $buffer;
  40123. }
  40124. }
  40125. <?php
  40126. declare (strict_types=1);
  40127. /*
  40128. * This file is part of PHPUnit.
  40129. *
  40130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40131. *
  40132. * For the full copyright and license information, please view the LICENSE
  40133. * file that was distributed with this source code.
  40134. */
  40135. namespace PHPUnit\Event\Test;
  40136. use PHPUnit\Event\Subscriber;
  40137. /**
  40138. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40139. */
  40140. interface DataProviderMethodFinishedSubscriber extends Subscriber
  40141. {
  40142. public function notify(\PHPUnit\Event\Test\DataProviderMethodFinished $event): void;
  40143. }
  40144. <?php
  40145. declare (strict_types=1);
  40146. /*
  40147. * This file is part of PHPUnit.
  40148. *
  40149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40150. *
  40151. * For the full copyright and license information, please view the LICENSE
  40152. * file that was distributed with this source code.
  40153. */
  40154. namespace PHPUnit\Event\Test;
  40155. use function sprintf;
  40156. use PHPUnit\Event\Code;
  40157. use PHPUnit\Event\Event;
  40158. use PHPUnit\Event\Telemetry;
  40159. /**
  40160. * @psalm-immutable
  40161. *
  40162. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40163. */
  40164. final class Finished implements Event
  40165. {
  40166. private readonly Telemetry\Info $telemetryInfo;
  40167. private readonly Code\Test $test;
  40168. private readonly int $numberOfAssertionsPerformed;
  40169. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, int $numberOfAssertionsPerformed)
  40170. {
  40171. $this->telemetryInfo = $telemetryInfo;
  40172. $this->test = $test;
  40173. $this->numberOfAssertionsPerformed = $numberOfAssertionsPerformed;
  40174. }
  40175. public function telemetryInfo(): Telemetry\Info
  40176. {
  40177. return $this->telemetryInfo;
  40178. }
  40179. public function test(): Code\Test
  40180. {
  40181. return $this->test;
  40182. }
  40183. public function numberOfAssertionsPerformed(): int
  40184. {
  40185. return $this->numberOfAssertionsPerformed;
  40186. }
  40187. public function asString(): string
  40188. {
  40189. return sprintf('Test Finished (%s)', $this->test->id());
  40190. }
  40191. }
  40192. <?php
  40193. declare (strict_types=1);
  40194. /*
  40195. * This file is part of PHPUnit.
  40196. *
  40197. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40198. *
  40199. * For the full copyright and license information, please view the LICENSE
  40200. * file that was distributed with this source code.
  40201. */
  40202. namespace PHPUnit\Event\Test;
  40203. use PHPUnit\Event\Subscriber;
  40204. /**
  40205. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40206. */
  40207. interface FinishedSubscriber extends Subscriber
  40208. {
  40209. public function notify(\PHPUnit\Event\Test\Finished $event): void;
  40210. }
  40211. <?php
  40212. declare (strict_types=1);
  40213. /*
  40214. * This file is part of PHPUnit.
  40215. *
  40216. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40217. *
  40218. * For the full copyright and license information, please view the LICENSE
  40219. * file that was distributed with this source code.
  40220. */
  40221. namespace PHPUnit\Event\Test;
  40222. use function sprintf;
  40223. use PHPUnit\Event\Code;
  40224. use PHPUnit\Event\Event;
  40225. use PHPUnit\Event\Telemetry;
  40226. /**
  40227. * @psalm-immutable
  40228. *
  40229. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40230. */
  40231. final class PreparationFailed implements Event
  40232. {
  40233. private readonly Telemetry\Info $telemetryInfo;
  40234. private readonly Code\Test $test;
  40235. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
  40236. {
  40237. $this->telemetryInfo = $telemetryInfo;
  40238. $this->test = $test;
  40239. }
  40240. public function telemetryInfo(): Telemetry\Info
  40241. {
  40242. return $this->telemetryInfo;
  40243. }
  40244. public function test(): Code\Test
  40245. {
  40246. return $this->test;
  40247. }
  40248. public function asString(): string
  40249. {
  40250. return sprintf('Test Preparation Failed (%s)', $this->test->id());
  40251. }
  40252. }
  40253. <?php
  40254. declare (strict_types=1);
  40255. /*
  40256. * This file is part of PHPUnit.
  40257. *
  40258. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40259. *
  40260. * For the full copyright and license information, please view the LICENSE
  40261. * file that was distributed with this source code.
  40262. */
  40263. namespace PHPUnit\Event\Test;
  40264. use PHPUnit\Event\Subscriber;
  40265. /**
  40266. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40267. */
  40268. interface PreparationFailedSubscriber extends Subscriber
  40269. {
  40270. public function notify(\PHPUnit\Event\Test\PreparationFailed $event): void;
  40271. }
  40272. <?php
  40273. declare (strict_types=1);
  40274. /*
  40275. * This file is part of PHPUnit.
  40276. *
  40277. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40278. *
  40279. * For the full copyright and license information, please view the LICENSE
  40280. * file that was distributed with this source code.
  40281. */
  40282. namespace PHPUnit\Event\Test;
  40283. use function sprintf;
  40284. use PHPUnit\Event\Code;
  40285. use PHPUnit\Event\Event;
  40286. use PHPUnit\Event\Telemetry;
  40287. /**
  40288. * @psalm-immutable
  40289. *
  40290. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40291. */
  40292. final class PreparationStarted implements Event
  40293. {
  40294. private readonly Telemetry\Info $telemetryInfo;
  40295. private readonly Code\Test $test;
  40296. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
  40297. {
  40298. $this->telemetryInfo = $telemetryInfo;
  40299. $this->test = $test;
  40300. }
  40301. public function telemetryInfo(): Telemetry\Info
  40302. {
  40303. return $this->telemetryInfo;
  40304. }
  40305. public function test(): Code\Test
  40306. {
  40307. return $this->test;
  40308. }
  40309. public function asString(): string
  40310. {
  40311. return sprintf('Test Preparation Started (%s)', $this->test->id());
  40312. }
  40313. }
  40314. <?php
  40315. declare (strict_types=1);
  40316. /*
  40317. * This file is part of PHPUnit.
  40318. *
  40319. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40320. *
  40321. * For the full copyright and license information, please view the LICENSE
  40322. * file that was distributed with this source code.
  40323. */
  40324. namespace PHPUnit\Event\Test;
  40325. use PHPUnit\Event\Subscriber;
  40326. /**
  40327. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40328. */
  40329. interface PreparationStartedSubscriber extends Subscriber
  40330. {
  40331. public function notify(\PHPUnit\Event\Test\PreparationStarted $event): void;
  40332. }
  40333. <?php
  40334. declare (strict_types=1);
  40335. /*
  40336. * This file is part of PHPUnit.
  40337. *
  40338. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40339. *
  40340. * For the full copyright and license information, please view the LICENSE
  40341. * file that was distributed with this source code.
  40342. */
  40343. namespace PHPUnit\Event\Test;
  40344. use function sprintf;
  40345. use PHPUnit\Event\Code;
  40346. use PHPUnit\Event\Event;
  40347. use PHPUnit\Event\Telemetry;
  40348. /**
  40349. * @psalm-immutable
  40350. *
  40351. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40352. */
  40353. final class Prepared implements Event
  40354. {
  40355. private readonly Telemetry\Info $telemetryInfo;
  40356. private readonly Code\Test $test;
  40357. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
  40358. {
  40359. $this->telemetryInfo = $telemetryInfo;
  40360. $this->test = $test;
  40361. }
  40362. public function telemetryInfo(): Telemetry\Info
  40363. {
  40364. return $this->telemetryInfo;
  40365. }
  40366. public function test(): Code\Test
  40367. {
  40368. return $this->test;
  40369. }
  40370. public function asString(): string
  40371. {
  40372. return sprintf('Test Prepared (%s)', $this->test->id());
  40373. }
  40374. }
  40375. <?php
  40376. declare (strict_types=1);
  40377. /*
  40378. * This file is part of PHPUnit.
  40379. *
  40380. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40381. *
  40382. * For the full copyright and license information, please view the LICENSE
  40383. * file that was distributed with this source code.
  40384. */
  40385. namespace PHPUnit\Event\Test;
  40386. use PHPUnit\Event\Subscriber;
  40387. /**
  40388. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40389. */
  40390. interface PreparedSubscriber extends Subscriber
  40391. {
  40392. public function notify(\PHPUnit\Event\Test\Prepared $event): void;
  40393. }
  40394. <?php
  40395. declare (strict_types=1);
  40396. /*
  40397. * This file is part of PHPUnit.
  40398. *
  40399. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40400. *
  40401. * For the full copyright and license information, please view the LICENSE
  40402. * file that was distributed with this source code.
  40403. */
  40404. namespace PHPUnit\Event\Test;
  40405. use const PHP_EOL;
  40406. use function sprintf;
  40407. use function trim;
  40408. use PHPUnit\Event\Code;
  40409. use PHPUnit\Event\Code\Throwable;
  40410. use PHPUnit\Event\Event;
  40411. use PHPUnit\Event\Telemetry;
  40412. /**
  40413. * @psalm-immutable
  40414. *
  40415. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40416. */
  40417. final class Errored implements Event
  40418. {
  40419. private readonly Telemetry\Info $telemetryInfo;
  40420. private readonly Code\Test $test;
  40421. private readonly Throwable $throwable;
  40422. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable)
  40423. {
  40424. $this->telemetryInfo = $telemetryInfo;
  40425. $this->test = $test;
  40426. $this->throwable = $throwable;
  40427. }
  40428. public function telemetryInfo(): Telemetry\Info
  40429. {
  40430. return $this->telemetryInfo;
  40431. }
  40432. public function test(): Code\Test
  40433. {
  40434. return $this->test;
  40435. }
  40436. public function throwable(): Throwable
  40437. {
  40438. return $this->throwable;
  40439. }
  40440. public function asString(): string
  40441. {
  40442. $message = trim($this->throwable->message());
  40443. if (!empty($message)) {
  40444. $message = PHP_EOL . $message;
  40445. }
  40446. return sprintf('Test Errored (%s)%s', $this->test->id(), $message);
  40447. }
  40448. }
  40449. <?php
  40450. declare (strict_types=1);
  40451. /*
  40452. * This file is part of PHPUnit.
  40453. *
  40454. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40455. *
  40456. * For the full copyright and license information, please view the LICENSE
  40457. * file that was distributed with this source code.
  40458. */
  40459. namespace PHPUnit\Event\Test;
  40460. use PHPUnit\Event\Subscriber;
  40461. /**
  40462. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40463. */
  40464. interface ErroredSubscriber extends Subscriber
  40465. {
  40466. public function notify(\PHPUnit\Event\Test\Errored $event): void;
  40467. }
  40468. <?php
  40469. declare (strict_types=1);
  40470. /*
  40471. * This file is part of PHPUnit.
  40472. *
  40473. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40474. *
  40475. * For the full copyright and license information, please view the LICENSE
  40476. * file that was distributed with this source code.
  40477. */
  40478. namespace PHPUnit\Event\Test;
  40479. use const PHP_EOL;
  40480. use function sprintf;
  40481. use function trim;
  40482. use PHPUnit\Event\Code;
  40483. use PHPUnit\Event\Code\ComparisonFailure;
  40484. use PHPUnit\Event\Code\Throwable;
  40485. use PHPUnit\Event\Event;
  40486. use PHPUnit\Event\Telemetry;
  40487. /**
  40488. * @psalm-immutable
  40489. *
  40490. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40491. */
  40492. final class Failed implements Event
  40493. {
  40494. private readonly Telemetry\Info $telemetryInfo;
  40495. private readonly Code\Test $test;
  40496. private readonly Throwable $throwable;
  40497. private readonly ?ComparisonFailure $comparisonFailure;
  40498. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure)
  40499. {
  40500. $this->telemetryInfo = $telemetryInfo;
  40501. $this->test = $test;
  40502. $this->throwable = $throwable;
  40503. $this->comparisonFailure = $comparisonFailure;
  40504. }
  40505. public function telemetryInfo(): Telemetry\Info
  40506. {
  40507. return $this->telemetryInfo;
  40508. }
  40509. public function test(): Code\Test
  40510. {
  40511. return $this->test;
  40512. }
  40513. public function throwable(): Throwable
  40514. {
  40515. return $this->throwable;
  40516. }
  40517. /**
  40518. * @psalm-assert-if-true !null $this->comparisonFailure
  40519. */
  40520. public function hasComparisonFailure(): bool
  40521. {
  40522. return $this->comparisonFailure !== null;
  40523. }
  40524. /**
  40525. * @throws NoComparisonFailureException
  40526. */
  40527. public function comparisonFailure(): ComparisonFailure
  40528. {
  40529. if ($this->comparisonFailure === null) {
  40530. throw new \PHPUnit\Event\Test\NoComparisonFailureException();
  40531. }
  40532. return $this->comparisonFailure;
  40533. }
  40534. public function asString(): string
  40535. {
  40536. $message = trim($this->throwable->message());
  40537. if (!empty($message)) {
  40538. $message = PHP_EOL . $message;
  40539. }
  40540. return sprintf('Test Failed (%s)%s', $this->test->id(), $message);
  40541. }
  40542. }
  40543. <?php
  40544. declare (strict_types=1);
  40545. /*
  40546. * This file is part of PHPUnit.
  40547. *
  40548. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40549. *
  40550. * For the full copyright and license information, please view the LICENSE
  40551. * file that was distributed with this source code.
  40552. */
  40553. namespace PHPUnit\Event\Test;
  40554. use PHPUnit\Event\Subscriber;
  40555. /**
  40556. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40557. */
  40558. interface FailedSubscriber extends Subscriber
  40559. {
  40560. public function notify(\PHPUnit\Event\Test\Failed $event): void;
  40561. }
  40562. <?php
  40563. declare (strict_types=1);
  40564. /*
  40565. * This file is part of PHPUnit.
  40566. *
  40567. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40568. *
  40569. * For the full copyright and license information, please view the LICENSE
  40570. * file that was distributed with this source code.
  40571. */
  40572. namespace PHPUnit\Event\Test;
  40573. use const PHP_EOL;
  40574. use function sprintf;
  40575. use function trim;
  40576. use PHPUnit\Event\Code;
  40577. use PHPUnit\Event\Code\Throwable;
  40578. use PHPUnit\Event\Event;
  40579. use PHPUnit\Event\Telemetry;
  40580. /**
  40581. * @psalm-immutable
  40582. *
  40583. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40584. */
  40585. final class MarkedIncomplete implements Event
  40586. {
  40587. private readonly Telemetry\Info $telemetryInfo;
  40588. private readonly Code\Test $test;
  40589. private readonly Throwable $throwable;
  40590. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable)
  40591. {
  40592. $this->telemetryInfo = $telemetryInfo;
  40593. $this->test = $test;
  40594. $this->throwable = $throwable;
  40595. }
  40596. public function telemetryInfo(): Telemetry\Info
  40597. {
  40598. return $this->telemetryInfo;
  40599. }
  40600. public function test(): Code\Test
  40601. {
  40602. return $this->test;
  40603. }
  40604. public function throwable(): Throwable
  40605. {
  40606. return $this->throwable;
  40607. }
  40608. public function asString(): string
  40609. {
  40610. $message = trim($this->throwable->message());
  40611. if (!empty($message)) {
  40612. $message = PHP_EOL . $message;
  40613. }
  40614. return sprintf('Test Marked Incomplete (%s)%s', $this->test->id(), $message);
  40615. }
  40616. }
  40617. <?php
  40618. declare (strict_types=1);
  40619. /*
  40620. * This file is part of PHPUnit.
  40621. *
  40622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40623. *
  40624. * For the full copyright and license information, please view the LICENSE
  40625. * file that was distributed with this source code.
  40626. */
  40627. namespace PHPUnit\Event\Test;
  40628. use PHPUnit\Event\Subscriber;
  40629. /**
  40630. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40631. */
  40632. interface MarkedIncompleteSubscriber extends Subscriber
  40633. {
  40634. public function notify(\PHPUnit\Event\Test\MarkedIncomplete $event): void;
  40635. }
  40636. <?php
  40637. declare (strict_types=1);
  40638. /*
  40639. * This file is part of PHPUnit.
  40640. *
  40641. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40642. *
  40643. * For the full copyright and license information, please view the LICENSE
  40644. * file that was distributed with this source code.
  40645. */
  40646. namespace PHPUnit\Event\Test;
  40647. use function sprintf;
  40648. use PHPUnit\Event\Code;
  40649. use PHPUnit\Event\Event;
  40650. use PHPUnit\Event\Telemetry;
  40651. /**
  40652. * @psalm-immutable
  40653. *
  40654. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40655. */
  40656. final class Passed implements Event
  40657. {
  40658. private readonly Telemetry\Info $telemetryInfo;
  40659. private readonly Code\Test $test;
  40660. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
  40661. {
  40662. $this->telemetryInfo = $telemetryInfo;
  40663. $this->test = $test;
  40664. }
  40665. public function telemetryInfo(): Telemetry\Info
  40666. {
  40667. return $this->telemetryInfo;
  40668. }
  40669. public function test(): Code\Test
  40670. {
  40671. return $this->test;
  40672. }
  40673. public function asString(): string
  40674. {
  40675. return sprintf('Test Passed (%s)', $this->test->id());
  40676. }
  40677. }
  40678. <?php
  40679. declare (strict_types=1);
  40680. /*
  40681. * This file is part of PHPUnit.
  40682. *
  40683. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40684. *
  40685. * For the full copyright and license information, please view the LICENSE
  40686. * file that was distributed with this source code.
  40687. */
  40688. namespace PHPUnit\Event\Test;
  40689. use PHPUnit\Event\Subscriber;
  40690. /**
  40691. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40692. */
  40693. interface PassedSubscriber extends Subscriber
  40694. {
  40695. public function notify(\PHPUnit\Event\Test\Passed $event): void;
  40696. }
  40697. <?php
  40698. declare (strict_types=1);
  40699. /*
  40700. * This file is part of PHPUnit.
  40701. *
  40702. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40703. *
  40704. * For the full copyright and license information, please view the LICENSE
  40705. * file that was distributed with this source code.
  40706. */
  40707. namespace PHPUnit\Event\Test;
  40708. use const PHP_EOL;
  40709. use function sprintf;
  40710. use PHPUnit\Event\Code;
  40711. use PHPUnit\Event\Event;
  40712. use PHPUnit\Event\Telemetry;
  40713. /**
  40714. * @psalm-immutable
  40715. *
  40716. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40717. */
  40718. final class Skipped implements Event
  40719. {
  40720. private readonly Telemetry\Info $telemetryInfo;
  40721. private readonly Code\Test $test;
  40722. private readonly string $message;
  40723. public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message)
  40724. {
  40725. $this->telemetryInfo = $telemetryInfo;
  40726. $this->test = $test;
  40727. $this->message = $message;
  40728. }
  40729. public function telemetryInfo(): Telemetry\Info
  40730. {
  40731. return $this->telemetryInfo;
  40732. }
  40733. public function test(): Code\Test
  40734. {
  40735. return $this->test;
  40736. }
  40737. public function message(): string
  40738. {
  40739. return $this->message;
  40740. }
  40741. public function asString(): string
  40742. {
  40743. $message = $this->message;
  40744. if (!empty($message)) {
  40745. $message = PHP_EOL . $message;
  40746. }
  40747. return sprintf('Test Skipped (%s)%s', $this->test->id(), $message);
  40748. }
  40749. }
  40750. <?php
  40751. declare (strict_types=1);
  40752. /*
  40753. * This file is part of PHPUnit.
  40754. *
  40755. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40756. *
  40757. * For the full copyright and license information, please view the LICENSE
  40758. * file that was distributed with this source code.
  40759. */
  40760. namespace PHPUnit\Event\Test;
  40761. use PHPUnit\Event\Subscriber;
  40762. /**
  40763. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40764. */
  40765. interface SkippedSubscriber extends Subscriber
  40766. {
  40767. public function notify(\PHPUnit\Event\Test\Skipped $event): void;
  40768. }
  40769. <?php
  40770. declare (strict_types=1);
  40771. /*
  40772. * This file is part of PHPUnit.
  40773. *
  40774. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40775. *
  40776. * For the full copyright and license information, please view the LICENSE
  40777. * file that was distributed with this source code.
  40778. */
  40779. namespace PHPUnit\Event\Test;
  40780. use const PHP_EOL;
  40781. use function sprintf;
  40782. use PHPUnit\Event\Event;
  40783. use PHPUnit\Event\Telemetry;
  40784. /**
  40785. * @psalm-immutable
  40786. *
  40787. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40788. */
  40789. final class PrintedUnexpectedOutput implements Event
  40790. {
  40791. private readonly Telemetry\Info $telemetryInfo;
  40792. /**
  40793. * @psalm-var non-empty-string
  40794. */
  40795. private readonly string $output;
  40796. /**
  40797. * @psalm-param non-empty-string $output
  40798. */
  40799. public function __construct(Telemetry\Info $telemetryInfo, string $output)
  40800. {
  40801. $this->telemetryInfo = $telemetryInfo;
  40802. $this->output = $output;
  40803. }
  40804. public function telemetryInfo(): Telemetry\Info
  40805. {
  40806. return $this->telemetryInfo;
  40807. }
  40808. /**
  40809. * @psalm-return non-empty-string
  40810. */
  40811. public function output(): string
  40812. {
  40813. return $this->output;
  40814. }
  40815. public function asString(): string
  40816. {
  40817. return sprintf('Test Printed Unexpected Output%s%s', PHP_EOL, $this->output);
  40818. }
  40819. }
  40820. <?php
  40821. declare (strict_types=1);
  40822. /*
  40823. * This file is part of PHPUnit.
  40824. *
  40825. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40826. *
  40827. * For the full copyright and license information, please view the LICENSE
  40828. * file that was distributed with this source code.
  40829. */
  40830. namespace PHPUnit\Event\Test;
  40831. use PHPUnit\Event\Subscriber;
  40832. /**
  40833. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40834. */
  40835. interface PrintedUnexpectedOutputSubscriber extends Subscriber
  40836. {
  40837. public function notify(\PHPUnit\Event\Test\PrintedUnexpectedOutput $event): void;
  40838. }
  40839. <?php
  40840. declare (strict_types=1);
  40841. /*
  40842. * This file is part of PHPUnit.
  40843. *
  40844. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40845. *
  40846. * For the full copyright and license information, please view the LICENSE
  40847. * file that was distributed with this source code.
  40848. */
  40849. namespace PHPUnit\Event\Test;
  40850. use function sprintf;
  40851. use PHPUnit\Event\Event;
  40852. use PHPUnit\Event\Telemetry;
  40853. /**
  40854. * @psalm-immutable
  40855. *
  40856. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40857. */
  40858. final class MockObjectCreated implements Event
  40859. {
  40860. private readonly Telemetry\Info $telemetryInfo;
  40861. /**
  40862. * @psalm-var class-string
  40863. */
  40864. private readonly string $className;
  40865. /**
  40866. * @psalm-param class-string $className
  40867. */
  40868. public function __construct(Telemetry\Info $telemetryInfo, string $className)
  40869. {
  40870. $this->telemetryInfo = $telemetryInfo;
  40871. $this->className = $className;
  40872. }
  40873. public function telemetryInfo(): Telemetry\Info
  40874. {
  40875. return $this->telemetryInfo;
  40876. }
  40877. /**
  40878. * @psalm-return class-string
  40879. */
  40880. public function className(): string
  40881. {
  40882. return $this->className;
  40883. }
  40884. public function asString(): string
  40885. {
  40886. return sprintf('Mock Object Created (%s)', $this->className);
  40887. }
  40888. }
  40889. <?php
  40890. declare (strict_types=1);
  40891. /*
  40892. * This file is part of PHPUnit.
  40893. *
  40894. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40895. *
  40896. * For the full copyright and license information, please view the LICENSE
  40897. * file that was distributed with this source code.
  40898. */
  40899. namespace PHPUnit\Event\Test;
  40900. use PHPUnit\Event\Subscriber;
  40901. /**
  40902. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40903. */
  40904. interface MockObjectCreatedSubscriber extends Subscriber
  40905. {
  40906. public function notify(\PHPUnit\Event\Test\MockObjectCreated $event): void;
  40907. }
  40908. <?php
  40909. declare (strict_types=1);
  40910. /*
  40911. * This file is part of PHPUnit.
  40912. *
  40913. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40914. *
  40915. * For the full copyright and license information, please view the LICENSE
  40916. * file that was distributed with this source code.
  40917. */
  40918. namespace PHPUnit\Event\Test;
  40919. use function sprintf;
  40920. use PHPUnit\Event\Event;
  40921. use PHPUnit\Event\Telemetry;
  40922. /**
  40923. * @psalm-immutable
  40924. *
  40925. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40926. */
  40927. final class MockObjectForAbstractClassCreated implements Event
  40928. {
  40929. private readonly Telemetry\Info $telemetryInfo;
  40930. /**
  40931. * @psalm-var class-string
  40932. */
  40933. private readonly string $className;
  40934. /**
  40935. * @psalm-param class-string $className
  40936. */
  40937. public function __construct(Telemetry\Info $telemetryInfo, string $className)
  40938. {
  40939. $this->telemetryInfo = $telemetryInfo;
  40940. $this->className = $className;
  40941. }
  40942. public function telemetryInfo(): Telemetry\Info
  40943. {
  40944. return $this->telemetryInfo;
  40945. }
  40946. /**
  40947. * @psalm-return class-string
  40948. */
  40949. public function className(): string
  40950. {
  40951. return $this->className;
  40952. }
  40953. public function asString(): string
  40954. {
  40955. return sprintf('Mock Object Created (%s)', $this->className);
  40956. }
  40957. }
  40958. <?php
  40959. declare (strict_types=1);
  40960. /*
  40961. * This file is part of PHPUnit.
  40962. *
  40963. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40964. *
  40965. * For the full copyright and license information, please view the LICENSE
  40966. * file that was distributed with this source code.
  40967. */
  40968. namespace PHPUnit\Event\Test;
  40969. use PHPUnit\Event\Subscriber;
  40970. /**
  40971. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40972. */
  40973. interface MockObjectForAbstractClassCreatedSubscriber extends Subscriber
  40974. {
  40975. public function notify(\PHPUnit\Event\Test\MockObjectForAbstractClassCreated $event): void;
  40976. }
  40977. <?php
  40978. declare (strict_types=1);
  40979. /*
  40980. * This file is part of PHPUnit.
  40981. *
  40982. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40983. *
  40984. * For the full copyright and license information, please view the LICENSE
  40985. * file that was distributed with this source code.
  40986. */
  40987. namespace PHPUnit\Event\Test;
  40988. use function implode;
  40989. use function sprintf;
  40990. use PHPUnit\Event\Event;
  40991. use PHPUnit\Event\Telemetry;
  40992. /**
  40993. * @psalm-immutable
  40994. *
  40995. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  40996. */
  40997. final class MockObjectForIntersectionOfInterfacesCreated implements Event
  40998. {
  40999. private readonly Telemetry\Info $telemetryInfo;
  41000. /**
  41001. * @psalm-var list<class-string>
  41002. */
  41003. private readonly array $interfaces;
  41004. /**
  41005. * @psalm-param list<class-string> $interfaces
  41006. */
  41007. public function __construct(Telemetry\Info $telemetryInfo, array $interfaces)
  41008. {
  41009. $this->telemetryInfo = $telemetryInfo;
  41010. $this->interfaces = $interfaces;
  41011. }
  41012. public function telemetryInfo(): Telemetry\Info
  41013. {
  41014. return $this->telemetryInfo;
  41015. }
  41016. /**
  41017. * @return list<class-string>
  41018. */
  41019. public function interfaces(): array
  41020. {
  41021. return $this->interfaces;
  41022. }
  41023. public function asString(): string
  41024. {
  41025. return sprintf('Mock Object Created (%s)', implode('&', $this->interfaces));
  41026. }
  41027. }
  41028. <?php
  41029. declare (strict_types=1);
  41030. /*
  41031. * This file is part of PHPUnit.
  41032. *
  41033. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41034. *
  41035. * For the full copyright and license information, please view the LICENSE
  41036. * file that was distributed with this source code.
  41037. */
  41038. namespace PHPUnit\Event\Test;
  41039. use PHPUnit\Event\Subscriber;
  41040. /**
  41041. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41042. */
  41043. interface MockObjectForIntersectionOfInterfacesCreatedSubscriber extends Subscriber
  41044. {
  41045. public function notify(\PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated $event): void;
  41046. }
  41047. <?php
  41048. declare (strict_types=1);
  41049. /*
  41050. * This file is part of PHPUnit.
  41051. *
  41052. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41053. *
  41054. * For the full copyright and license information, please view the LICENSE
  41055. * file that was distributed with this source code.
  41056. */
  41057. namespace PHPUnit\Event\Test;
  41058. use function sprintf;
  41059. use PHPUnit\Event\Event;
  41060. use PHPUnit\Event\Telemetry;
  41061. /**
  41062. * @psalm-immutable
  41063. *
  41064. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41065. */
  41066. final class MockObjectForTraitCreated implements Event
  41067. {
  41068. private readonly Telemetry\Info $telemetryInfo;
  41069. /**
  41070. * @psalm-var trait-string
  41071. */
  41072. private readonly string $traitName;
  41073. /**
  41074. * @psalm-param trait-string $traitName
  41075. */
  41076. public function __construct(Telemetry\Info $telemetryInfo, string $traitName)
  41077. {
  41078. $this->telemetryInfo = $telemetryInfo;
  41079. $this->traitName = $traitName;
  41080. }
  41081. public function telemetryInfo(): Telemetry\Info
  41082. {
  41083. return $this->telemetryInfo;
  41084. }
  41085. /**
  41086. * @psalm-return trait-string
  41087. */
  41088. public function traitName(): string
  41089. {
  41090. return $this->traitName;
  41091. }
  41092. public function asString(): string
  41093. {
  41094. return sprintf('Mock Object Created (%s)', $this->traitName);
  41095. }
  41096. }
  41097. <?php
  41098. declare (strict_types=1);
  41099. /*
  41100. * This file is part of PHPUnit.
  41101. *
  41102. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41103. *
  41104. * For the full copyright and license information, please view the LICENSE
  41105. * file that was distributed with this source code.
  41106. */
  41107. namespace PHPUnit\Event\Test;
  41108. use PHPUnit\Event\Subscriber;
  41109. /**
  41110. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41111. */
  41112. interface MockObjectForTraitCreatedSubscriber extends Subscriber
  41113. {
  41114. public function notify(\PHPUnit\Event\Test\MockObjectForTraitCreated $event): void;
  41115. }
  41116. <?php
  41117. declare (strict_types=1);
  41118. /*
  41119. * This file is part of PHPUnit.
  41120. *
  41121. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41122. *
  41123. * For the full copyright and license information, please view the LICENSE
  41124. * file that was distributed with this source code.
  41125. */
  41126. namespace PHPUnit\Event\Test;
  41127. use function sprintf;
  41128. use PHPUnit\Event\Event;
  41129. use PHPUnit\Event\Telemetry;
  41130. /**
  41131. * @psalm-immutable
  41132. *
  41133. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41134. */
  41135. final class MockObjectFromWsdlCreated implements Event
  41136. {
  41137. private readonly Telemetry\Info $telemetryInfo;
  41138. private readonly string $wsdlFile;
  41139. /**
  41140. * @psalm-var class-string
  41141. */
  41142. private readonly string $originalClassName;
  41143. /**
  41144. * @psalm-var class-string
  41145. */
  41146. private readonly string $mockClassName;
  41147. /**
  41148. * @psalm-var list<string>
  41149. */
  41150. private readonly array $methods;
  41151. private readonly bool $callOriginalConstructor;
  41152. private readonly array $options;
  41153. /**
  41154. * @psalm-param class-string $originalClassName
  41155. * @psalm-param class-string $mockClassName
  41156. */
  41157. public function __construct(Telemetry\Info $telemetryInfo, string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options)
  41158. {
  41159. $this->telemetryInfo = $telemetryInfo;
  41160. $this->wsdlFile = $wsdlFile;
  41161. $this->originalClassName = $originalClassName;
  41162. $this->mockClassName = $mockClassName;
  41163. $this->methods = $methods;
  41164. $this->callOriginalConstructor = $callOriginalConstructor;
  41165. $this->options = $options;
  41166. }
  41167. public function telemetryInfo(): Telemetry\Info
  41168. {
  41169. return $this->telemetryInfo;
  41170. }
  41171. public function wsdlFile(): string
  41172. {
  41173. return $this->wsdlFile;
  41174. }
  41175. /**
  41176. * @psalm-return class-string
  41177. */
  41178. public function originalClassName(): string
  41179. {
  41180. return $this->originalClassName;
  41181. }
  41182. /**
  41183. * @psalm-return class-string
  41184. */
  41185. public function mockClassName(): string
  41186. {
  41187. return $this->mockClassName;
  41188. }
  41189. /**
  41190. * @psalm-return list<string>
  41191. */
  41192. public function methods(): array
  41193. {
  41194. return $this->methods;
  41195. }
  41196. public function callOriginalConstructor(): bool
  41197. {
  41198. return $this->callOriginalConstructor;
  41199. }
  41200. public function options(): array
  41201. {
  41202. return $this->options;
  41203. }
  41204. public function asString(): string
  41205. {
  41206. return sprintf('Mock Object Created (%s)', $this->wsdlFile);
  41207. }
  41208. }
  41209. <?php
  41210. declare (strict_types=1);
  41211. /*
  41212. * This file is part of PHPUnit.
  41213. *
  41214. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41215. *
  41216. * For the full copyright and license information, please view the LICENSE
  41217. * file that was distributed with this source code.
  41218. */
  41219. namespace PHPUnit\Event\Test;
  41220. use PHPUnit\Event\Subscriber;
  41221. /**
  41222. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41223. */
  41224. interface MockObjectFromWsdlCreatedSubscriber extends Subscriber
  41225. {
  41226. public function notify(\PHPUnit\Event\Test\MockObjectFromWsdlCreated $event): void;
  41227. }
  41228. <?php
  41229. declare (strict_types=1);
  41230. /*
  41231. * This file is part of PHPUnit.
  41232. *
  41233. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41234. *
  41235. * For the full copyright and license information, please view the LICENSE
  41236. * file that was distributed with this source code.
  41237. */
  41238. namespace PHPUnit\Event\Test;
  41239. use function sprintf;
  41240. use PHPUnit\Event\Event;
  41241. use PHPUnit\Event\Telemetry;
  41242. /**
  41243. * @psalm-immutable
  41244. *
  41245. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41246. */
  41247. final class PartialMockObjectCreated implements Event
  41248. {
  41249. private readonly Telemetry\Info $telemetryInfo;
  41250. /**
  41251. * @psalm-var class-string
  41252. */
  41253. private readonly string $className;
  41254. /**
  41255. * @psalm-var list<string>
  41256. */
  41257. private readonly array $methodNames;
  41258. /**
  41259. * @psalm-param class-string $className
  41260. */
  41261. public function __construct(Telemetry\Info $telemetryInfo, string $className, string ...$methodNames)
  41262. {
  41263. $this->telemetryInfo = $telemetryInfo;
  41264. $this->className = $className;
  41265. $this->methodNames = $methodNames;
  41266. }
  41267. public function telemetryInfo(): Telemetry\Info
  41268. {
  41269. return $this->telemetryInfo;
  41270. }
  41271. /**
  41272. * @psalm-return class-string
  41273. */
  41274. public function className(): string
  41275. {
  41276. return $this->className;
  41277. }
  41278. /**
  41279. * @psalm-return list<string>
  41280. */
  41281. public function methodNames(): array
  41282. {
  41283. return $this->methodNames;
  41284. }
  41285. public function asString(): string
  41286. {
  41287. return sprintf('Partial Mock Object Created (%s)', $this->className);
  41288. }
  41289. }
  41290. <?php
  41291. declare (strict_types=1);
  41292. /*
  41293. * This file is part of PHPUnit.
  41294. *
  41295. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41296. *
  41297. * For the full copyright and license information, please view the LICENSE
  41298. * file that was distributed with this source code.
  41299. */
  41300. namespace PHPUnit\Event\Test;
  41301. use PHPUnit\Event\Subscriber;
  41302. /**
  41303. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41304. */
  41305. interface PartialMockObjectCreatedSubscriber extends Subscriber
  41306. {
  41307. public function notify(\PHPUnit\Event\Test\PartialMockObjectCreated $event): void;
  41308. }
  41309. <?php
  41310. declare (strict_types=1);
  41311. /*
  41312. * This file is part of PHPUnit.
  41313. *
  41314. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41315. *
  41316. * For the full copyright and license information, please view the LICENSE
  41317. * file that was distributed with this source code.
  41318. */
  41319. namespace PHPUnit\Event\Test;
  41320. use function sprintf;
  41321. use PHPUnit\Event\Event;
  41322. use PHPUnit\Event\Telemetry;
  41323. /**
  41324. * @psalm-immutable
  41325. *
  41326. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41327. */
  41328. final class TestProxyCreated implements Event
  41329. {
  41330. private readonly Telemetry\Info $telemetryInfo;
  41331. /**
  41332. * @psalm-var class-string
  41333. */
  41334. private readonly string $className;
  41335. private readonly string $constructorArguments;
  41336. /**
  41337. * @psalm-param class-string $className
  41338. */
  41339. public function __construct(Telemetry\Info $telemetryInfo, string $className, string $constructorArguments)
  41340. {
  41341. $this->telemetryInfo = $telemetryInfo;
  41342. $this->className = $className;
  41343. $this->constructorArguments = $constructorArguments;
  41344. }
  41345. public function telemetryInfo(): Telemetry\Info
  41346. {
  41347. return $this->telemetryInfo;
  41348. }
  41349. /**
  41350. * @psalm-return class-string
  41351. */
  41352. public function className(): string
  41353. {
  41354. return $this->className;
  41355. }
  41356. public function constructorArguments(): string
  41357. {
  41358. return $this->constructorArguments;
  41359. }
  41360. public function asString(): string
  41361. {
  41362. return sprintf('Test Proxy Created (%s)', $this->className);
  41363. }
  41364. }
  41365. <?php
  41366. declare (strict_types=1);
  41367. /*
  41368. * This file is part of PHPUnit.
  41369. *
  41370. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41371. *
  41372. * For the full copyright and license information, please view the LICENSE
  41373. * file that was distributed with this source code.
  41374. */
  41375. namespace PHPUnit\Event\Test;
  41376. use PHPUnit\Event\Subscriber;
  41377. /**
  41378. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41379. */
  41380. interface TestProxyCreatedSubscriber extends Subscriber
  41381. {
  41382. public function notify(\PHPUnit\Event\Test\TestProxyCreated $event): void;
  41383. }
  41384. <?php
  41385. declare (strict_types=1);
  41386. /*
  41387. * This file is part of PHPUnit.
  41388. *
  41389. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41390. *
  41391. * For the full copyright and license information, please view the LICENSE
  41392. * file that was distributed with this source code.
  41393. */
  41394. namespace PHPUnit\Event\Test;
  41395. use function sprintf;
  41396. use PHPUnit\Event\Event;
  41397. use PHPUnit\Event\Telemetry;
  41398. /**
  41399. * @psalm-immutable
  41400. *
  41401. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41402. */
  41403. final class TestStubCreated implements Event
  41404. {
  41405. private readonly Telemetry\Info $telemetryInfo;
  41406. /**
  41407. * @var class-string
  41408. */
  41409. private readonly string $className;
  41410. /**
  41411. * @psalm-param class-string $className
  41412. */
  41413. public function __construct(Telemetry\Info $telemetryInfo, string $className)
  41414. {
  41415. $this->telemetryInfo = $telemetryInfo;
  41416. $this->className = $className;
  41417. }
  41418. public function telemetryInfo(): Telemetry\Info
  41419. {
  41420. return $this->telemetryInfo;
  41421. }
  41422. /**
  41423. * @return class-string
  41424. */
  41425. public function className(): string
  41426. {
  41427. return $this->className;
  41428. }
  41429. public function asString(): string
  41430. {
  41431. return sprintf('Test Stub Created (%s)', $this->className);
  41432. }
  41433. }
  41434. <?php
  41435. declare (strict_types=1);
  41436. /*
  41437. * This file is part of PHPUnit.
  41438. *
  41439. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41440. *
  41441. * For the full copyright and license information, please view the LICENSE
  41442. * file that was distributed with this source code.
  41443. */
  41444. namespace PHPUnit\Event\Test;
  41445. use PHPUnit\Event\Subscriber;
  41446. /**
  41447. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41448. */
  41449. interface TestStubCreatedSubscriber extends Subscriber
  41450. {
  41451. public function notify(\PHPUnit\Event\Test\TestStubCreated $event): void;
  41452. }
  41453. <?php
  41454. declare (strict_types=1);
  41455. /*
  41456. * This file is part of PHPUnit.
  41457. *
  41458. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41459. *
  41460. * For the full copyright and license information, please view the LICENSE
  41461. * file that was distributed with this source code.
  41462. */
  41463. namespace PHPUnit\Event\Test;
  41464. use function implode;
  41465. use function sprintf;
  41466. use PHPUnit\Event\Event;
  41467. use PHPUnit\Event\Telemetry;
  41468. /**
  41469. * @psalm-immutable
  41470. *
  41471. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41472. */
  41473. final class TestStubForIntersectionOfInterfacesCreated implements Event
  41474. {
  41475. private readonly Telemetry\Info $telemetryInfo;
  41476. /**
  41477. * @psalm-var list<class-string>
  41478. */
  41479. private readonly array $interfaces;
  41480. /**
  41481. * @psalm-param list<class-string> $interfaces
  41482. */
  41483. public function __construct(Telemetry\Info $telemetryInfo, array $interfaces)
  41484. {
  41485. $this->telemetryInfo = $telemetryInfo;
  41486. $this->interfaces = $interfaces;
  41487. }
  41488. public function telemetryInfo(): Telemetry\Info
  41489. {
  41490. return $this->telemetryInfo;
  41491. }
  41492. /**
  41493. * @return list<class-string>
  41494. */
  41495. public function interfaces(): array
  41496. {
  41497. return $this->interfaces;
  41498. }
  41499. public function asString(): string
  41500. {
  41501. return sprintf('Test Stub Created (%s)', implode('&', $this->interfaces));
  41502. }
  41503. }
  41504. <?php
  41505. declare (strict_types=1);
  41506. /*
  41507. * This file is part of PHPUnit.
  41508. *
  41509. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41510. *
  41511. * For the full copyright and license information, please view the LICENSE
  41512. * file that was distributed with this source code.
  41513. */
  41514. namespace PHPUnit\Event\Test;
  41515. use PHPUnit\Event\Subscriber;
  41516. /**
  41517. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41518. */
  41519. interface TestStubForIntersectionOfInterfacesCreatedSubscriber extends Subscriber
  41520. {
  41521. public function notify(\PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated $event): void;
  41522. }
  41523. <?php
  41524. declare (strict_types=1);
  41525. /*
  41526. * This file is part of PHPUnit.
  41527. *
  41528. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41529. *
  41530. * For the full copyright and license information, please view the LICENSE
  41531. * file that was distributed with this source code.
  41532. */
  41533. namespace PHPUnit\Event\TestRunner;
  41534. use function sprintf;
  41535. use PHPUnit\Event\Event;
  41536. use PHPUnit\Event\Telemetry;
  41537. /**
  41538. * @psalm-immutable
  41539. *
  41540. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41541. */
  41542. final class BootstrapFinished implements Event
  41543. {
  41544. private readonly Telemetry\Info $telemetryInfo;
  41545. private readonly string $filename;
  41546. public function __construct(Telemetry\Info $telemetryInfo, string $filename)
  41547. {
  41548. $this->telemetryInfo = $telemetryInfo;
  41549. $this->filename = $filename;
  41550. }
  41551. public function telemetryInfo(): Telemetry\Info
  41552. {
  41553. return $this->telemetryInfo;
  41554. }
  41555. public function filename(): string
  41556. {
  41557. return $this->filename;
  41558. }
  41559. public function asString(): string
  41560. {
  41561. return sprintf('Bootstrap Finished (%s)', $this->filename);
  41562. }
  41563. }
  41564. <?php
  41565. declare (strict_types=1);
  41566. /*
  41567. * This file is part of PHPUnit.
  41568. *
  41569. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41570. *
  41571. * For the full copyright and license information, please view the LICENSE
  41572. * file that was distributed with this source code.
  41573. */
  41574. namespace PHPUnit\Event\TestRunner;
  41575. use PHPUnit\Event\Subscriber;
  41576. /**
  41577. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41578. */
  41579. interface BootstrapFinishedSubscriber extends Subscriber
  41580. {
  41581. public function notify(\PHPUnit\Event\TestRunner\BootstrapFinished $event): void;
  41582. }
  41583. <?php
  41584. declare (strict_types=1);
  41585. /*
  41586. * This file is part of PHPUnit.
  41587. *
  41588. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41589. *
  41590. * For the full copyright and license information, please view the LICENSE
  41591. * file that was distributed with this source code.
  41592. */
  41593. namespace PHPUnit\Event\TestRunner;
  41594. use PHPUnit\Event\Event;
  41595. use PHPUnit\Event\Telemetry;
  41596. use PHPUnit\TextUI\Configuration\Configuration;
  41597. /**
  41598. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41599. */
  41600. final class Configured implements Event
  41601. {
  41602. private readonly Telemetry\Info $telemetryInfo;
  41603. private readonly Configuration $configuration;
  41604. public function __construct(Telemetry\Info $telemetryInfo, Configuration $configuration)
  41605. {
  41606. $this->telemetryInfo = $telemetryInfo;
  41607. $this->configuration = $configuration;
  41608. }
  41609. public function telemetryInfo(): Telemetry\Info
  41610. {
  41611. return $this->telemetryInfo;
  41612. }
  41613. public function configuration(): Configuration
  41614. {
  41615. return $this->configuration;
  41616. }
  41617. public function asString(): string
  41618. {
  41619. return 'Test Runner Configured';
  41620. }
  41621. }
  41622. <?php
  41623. declare (strict_types=1);
  41624. /*
  41625. * This file is part of PHPUnit.
  41626. *
  41627. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41628. *
  41629. * For the full copyright and license information, please view the LICENSE
  41630. * file that was distributed with this source code.
  41631. */
  41632. namespace PHPUnit\Event\TestRunner;
  41633. use PHPUnit\Event\Subscriber;
  41634. /**
  41635. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41636. */
  41637. interface ConfiguredSubscriber extends Subscriber
  41638. {
  41639. public function notify(\PHPUnit\Event\TestRunner\Configured $event): void;
  41640. }
  41641. <?php
  41642. declare (strict_types=1);
  41643. /*
  41644. * This file is part of PHPUnit.
  41645. *
  41646. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41647. *
  41648. * For the full copyright and license information, please view the LICENSE
  41649. * file that was distributed with this source code.
  41650. */
  41651. namespace PHPUnit\Event\TestRunner;
  41652. use function sprintf;
  41653. use PHPUnit\Event\Event;
  41654. use PHPUnit\Event\Telemetry;
  41655. /**
  41656. * @psalm-immutable
  41657. *
  41658. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41659. */
  41660. final class DeprecationTriggered implements Event
  41661. {
  41662. private readonly Telemetry\Info $telemetryInfo;
  41663. private readonly string $message;
  41664. public function __construct(Telemetry\Info $telemetryInfo, string $message)
  41665. {
  41666. $this->telemetryInfo = $telemetryInfo;
  41667. $this->message = $message;
  41668. }
  41669. public function telemetryInfo(): Telemetry\Info
  41670. {
  41671. return $this->telemetryInfo;
  41672. }
  41673. public function message(): string
  41674. {
  41675. return $this->message;
  41676. }
  41677. public function asString(): string
  41678. {
  41679. return sprintf('Test Runner Triggered Deprecation (%s)', $this->message);
  41680. }
  41681. }
  41682. <?php
  41683. declare (strict_types=1);
  41684. /*
  41685. * This file is part of PHPUnit.
  41686. *
  41687. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41688. *
  41689. * For the full copyright and license information, please view the LICENSE
  41690. * file that was distributed with this source code.
  41691. */
  41692. namespace PHPUnit\Event\TestRunner;
  41693. use PHPUnit\Event\Subscriber;
  41694. /**
  41695. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41696. */
  41697. interface DeprecationTriggeredSubscriber extends Subscriber
  41698. {
  41699. public function notify(\PHPUnit\Event\TestRunner\DeprecationTriggered $event): void;
  41700. }
  41701. <?php
  41702. declare (strict_types=1);
  41703. /*
  41704. * This file is part of PHPUnit.
  41705. *
  41706. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41707. *
  41708. * For the full copyright and license information, please view the LICENSE
  41709. * file that was distributed with this source code.
  41710. */
  41711. namespace PHPUnit\Event\TestRunner;
  41712. use PHPUnit\Event\Event;
  41713. use PHPUnit\Event\Telemetry;
  41714. /**
  41715. * @psalm-immutable
  41716. *
  41717. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41718. */
  41719. final class EventFacadeSealed implements Event
  41720. {
  41721. private readonly Telemetry\Info $telemetryInfo;
  41722. public function __construct(Telemetry\Info $telemetryInfo)
  41723. {
  41724. $this->telemetryInfo = $telemetryInfo;
  41725. }
  41726. public function telemetryInfo(): Telemetry\Info
  41727. {
  41728. return $this->telemetryInfo;
  41729. }
  41730. public function asString(): string
  41731. {
  41732. return 'Event Facade Sealed';
  41733. }
  41734. }
  41735. <?php
  41736. declare (strict_types=1);
  41737. /*
  41738. * This file is part of PHPUnit.
  41739. *
  41740. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41741. *
  41742. * For the full copyright and license information, please view the LICENSE
  41743. * file that was distributed with this source code.
  41744. */
  41745. namespace PHPUnit\Event\TestRunner;
  41746. use PHPUnit\Event\Subscriber;
  41747. /**
  41748. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41749. */
  41750. interface EventFacadeSealedSubscriber extends Subscriber
  41751. {
  41752. public function notify(\PHPUnit\Event\TestRunner\EventFacadeSealed $event): void;
  41753. }
  41754. <?php
  41755. declare (strict_types=1);
  41756. /*
  41757. * This file is part of PHPUnit.
  41758. *
  41759. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41760. *
  41761. * For the full copyright and license information, please view the LICENSE
  41762. * file that was distributed with this source code.
  41763. */
  41764. namespace PHPUnit\Event\TestRunner;
  41765. use PHPUnit\Event\Event;
  41766. use PHPUnit\Event\Telemetry;
  41767. /**
  41768. * @psalm-immutable
  41769. *
  41770. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41771. */
  41772. final class ExecutionAborted implements Event
  41773. {
  41774. private readonly Telemetry\Info $telemetryInfo;
  41775. public function __construct(Telemetry\Info $telemetryInfo)
  41776. {
  41777. $this->telemetryInfo = $telemetryInfo;
  41778. }
  41779. public function telemetryInfo(): Telemetry\Info
  41780. {
  41781. return $this->telemetryInfo;
  41782. }
  41783. public function asString(): string
  41784. {
  41785. return 'Test Runner Execution Aborted';
  41786. }
  41787. }
  41788. <?php
  41789. declare (strict_types=1);
  41790. /*
  41791. * This file is part of PHPUnit.
  41792. *
  41793. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41794. *
  41795. * For the full copyright and license information, please view the LICENSE
  41796. * file that was distributed with this source code.
  41797. */
  41798. namespace PHPUnit\Event\TestRunner;
  41799. use PHPUnit\Event\Subscriber;
  41800. /**
  41801. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41802. */
  41803. interface ExecutionAbortedSubscriber extends Subscriber
  41804. {
  41805. public function notify(\PHPUnit\Event\TestRunner\ExecutionAborted $event): void;
  41806. }
  41807. <?php
  41808. declare (strict_types=1);
  41809. /*
  41810. * This file is part of PHPUnit.
  41811. *
  41812. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41813. *
  41814. * For the full copyright and license information, please view the LICENSE
  41815. * file that was distributed with this source code.
  41816. */
  41817. namespace PHPUnit\Event\TestRunner;
  41818. use PHPUnit\Event\Event;
  41819. use PHPUnit\Event\Telemetry;
  41820. /**
  41821. * @psalm-immutable
  41822. *
  41823. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41824. */
  41825. final class ExecutionFinished implements Event
  41826. {
  41827. private readonly Telemetry\Info $telemetryInfo;
  41828. public function __construct(Telemetry\Info $telemetryInfo)
  41829. {
  41830. $this->telemetryInfo = $telemetryInfo;
  41831. }
  41832. public function telemetryInfo(): Telemetry\Info
  41833. {
  41834. return $this->telemetryInfo;
  41835. }
  41836. public function asString(): string
  41837. {
  41838. return 'Test Runner Execution Finished';
  41839. }
  41840. }
  41841. <?php
  41842. declare (strict_types=1);
  41843. /*
  41844. * This file is part of PHPUnit.
  41845. *
  41846. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41847. *
  41848. * For the full copyright and license information, please view the LICENSE
  41849. * file that was distributed with this source code.
  41850. */
  41851. namespace PHPUnit\Event\TestRunner;
  41852. use PHPUnit\Event\Subscriber;
  41853. /**
  41854. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41855. */
  41856. interface ExecutionFinishedSubscriber extends Subscriber
  41857. {
  41858. public function notify(\PHPUnit\Event\TestRunner\ExecutionFinished $event): void;
  41859. }
  41860. <?php
  41861. declare (strict_types=1);
  41862. /*
  41863. * This file is part of PHPUnit.
  41864. *
  41865. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41866. *
  41867. * For the full copyright and license information, please view the LICENSE
  41868. * file that was distributed with this source code.
  41869. */
  41870. namespace PHPUnit\Event\TestRunner;
  41871. use function sprintf;
  41872. use PHPUnit\Event\Event;
  41873. use PHPUnit\Event\Telemetry;
  41874. use PHPUnit\Event\TestSuite\TestSuite;
  41875. /**
  41876. * @psalm-immutable
  41877. *
  41878. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41879. */
  41880. final class ExecutionStarted implements Event
  41881. {
  41882. private readonly Telemetry\Info $telemetryInfo;
  41883. private readonly TestSuite $testSuite;
  41884. public function __construct(Telemetry\Info $telemetryInfo, TestSuite $testSuite)
  41885. {
  41886. $this->telemetryInfo = $telemetryInfo;
  41887. $this->testSuite = $testSuite;
  41888. }
  41889. public function telemetryInfo(): Telemetry\Info
  41890. {
  41891. return $this->telemetryInfo;
  41892. }
  41893. public function testSuite(): TestSuite
  41894. {
  41895. return $this->testSuite;
  41896. }
  41897. public function asString(): string
  41898. {
  41899. return sprintf('Test Runner Execution Started (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
  41900. }
  41901. }
  41902. <?php
  41903. declare (strict_types=1);
  41904. /*
  41905. * This file is part of PHPUnit.
  41906. *
  41907. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41908. *
  41909. * For the full copyright and license information, please view the LICENSE
  41910. * file that was distributed with this source code.
  41911. */
  41912. namespace PHPUnit\Event\TestRunner;
  41913. use PHPUnit\Event\Subscriber;
  41914. /**
  41915. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41916. */
  41917. interface ExecutionStartedSubscriber extends Subscriber
  41918. {
  41919. public function notify(\PHPUnit\Event\TestRunner\ExecutionStarted $event): void;
  41920. }
  41921. <?php
  41922. declare (strict_types=1);
  41923. /*
  41924. * This file is part of PHPUnit.
  41925. *
  41926. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41927. *
  41928. * For the full copyright and license information, please view the LICENSE
  41929. * file that was distributed with this source code.
  41930. */
  41931. namespace PHPUnit\Event\TestRunner;
  41932. use function sprintf;
  41933. use PHPUnit\Event\Event;
  41934. use PHPUnit\Event\Telemetry;
  41935. /**
  41936. * @psalm-immutable
  41937. *
  41938. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41939. */
  41940. final class ExtensionBootstrapped implements Event
  41941. {
  41942. private readonly Telemetry\Info $telemetryInfo;
  41943. /**
  41944. * @psalm-var class-string
  41945. */
  41946. private readonly string $className;
  41947. /**
  41948. * @psalm-var array<string, string>
  41949. */
  41950. private readonly array $parameters;
  41951. /**
  41952. * @psalm-param class-string $className
  41953. * @psalm-param array<string, string> $parameters
  41954. */
  41955. public function __construct(Telemetry\Info $telemetryInfo, string $className, array $parameters)
  41956. {
  41957. $this->telemetryInfo = $telemetryInfo;
  41958. $this->className = $className;
  41959. $this->parameters = $parameters;
  41960. }
  41961. public function telemetryInfo(): Telemetry\Info
  41962. {
  41963. return $this->telemetryInfo;
  41964. }
  41965. /**
  41966. * @psalm-return class-string
  41967. */
  41968. public function className(): string
  41969. {
  41970. return $this->className;
  41971. }
  41972. /**
  41973. * @psalm-return array<string, string>
  41974. */
  41975. public function parameters(): array
  41976. {
  41977. return $this->parameters;
  41978. }
  41979. public function asString(): string
  41980. {
  41981. return sprintf('Extension Bootstrapped (%s)', $this->className);
  41982. }
  41983. }
  41984. <?php
  41985. declare (strict_types=1);
  41986. /*
  41987. * This file is part of PHPUnit.
  41988. *
  41989. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  41990. *
  41991. * For the full copyright and license information, please view the LICENSE
  41992. * file that was distributed with this source code.
  41993. */
  41994. namespace PHPUnit\Event\TestRunner;
  41995. use PHPUnit\Event\Subscriber;
  41996. /**
  41997. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  41998. */
  41999. interface ExtensionBootstrappedSubscriber extends Subscriber
  42000. {
  42001. public function notify(\PHPUnit\Event\TestRunner\ExtensionBootstrapped $event): void;
  42002. }
  42003. <?php
  42004. declare (strict_types=1);
  42005. /*
  42006. * This file is part of PHPUnit.
  42007. *
  42008. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42009. *
  42010. * For the full copyright and license information, please view the LICENSE
  42011. * file that was distributed with this source code.
  42012. */
  42013. namespace PHPUnit\Event\TestRunner;
  42014. use function sprintf;
  42015. use PHPUnit\Event\Event;
  42016. use PHPUnit\Event\Telemetry;
  42017. /**
  42018. * @psalm-immutable
  42019. *
  42020. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42021. */
  42022. final class ExtensionLoadedFromPhar implements Event
  42023. {
  42024. private readonly Telemetry\Info $telemetryInfo;
  42025. private readonly string $filename;
  42026. private readonly string $name;
  42027. private readonly string $version;
  42028. public function __construct(Telemetry\Info $telemetryInfo, string $filename, string $name, string $version)
  42029. {
  42030. $this->telemetryInfo = $telemetryInfo;
  42031. $this->filename = $filename;
  42032. $this->name = $name;
  42033. $this->version = $version;
  42034. }
  42035. public function telemetryInfo(): Telemetry\Info
  42036. {
  42037. return $this->telemetryInfo;
  42038. }
  42039. public function filename(): string
  42040. {
  42041. return $this->filename;
  42042. }
  42043. public function name(): string
  42044. {
  42045. return $this->name;
  42046. }
  42047. public function version(): string
  42048. {
  42049. return $this->version;
  42050. }
  42051. public function asString(): string
  42052. {
  42053. return sprintf('Extension Loaded from PHAR (%s %s)', $this->name, $this->version);
  42054. }
  42055. }
  42056. <?php
  42057. declare (strict_types=1);
  42058. /*
  42059. * This file is part of PHPUnit.
  42060. *
  42061. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42062. *
  42063. * For the full copyright and license information, please view the LICENSE
  42064. * file that was distributed with this source code.
  42065. */
  42066. namespace PHPUnit\Event\TestRunner;
  42067. use PHPUnit\Event\Subscriber;
  42068. /**
  42069. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42070. */
  42071. interface ExtensionLoadedFromPharSubscriber extends Subscriber
  42072. {
  42073. public function notify(\PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar $event): void;
  42074. }
  42075. <?php
  42076. declare (strict_types=1);
  42077. /*
  42078. * This file is part of PHPUnit.
  42079. *
  42080. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42081. *
  42082. * For the full copyright and license information, please view the LICENSE
  42083. * file that was distributed with this source code.
  42084. */
  42085. namespace PHPUnit\Event\TestRunner;
  42086. use PHPUnit\Event\Event;
  42087. use PHPUnit\Event\Telemetry;
  42088. /**
  42089. * @psalm-immutable
  42090. *
  42091. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42092. */
  42093. final class Finished implements Event
  42094. {
  42095. private readonly Telemetry\Info $telemetryInfo;
  42096. public function __construct(Telemetry\Info $telemetryInfo)
  42097. {
  42098. $this->telemetryInfo = $telemetryInfo;
  42099. }
  42100. public function telemetryInfo(): Telemetry\Info
  42101. {
  42102. return $this->telemetryInfo;
  42103. }
  42104. public function asString(): string
  42105. {
  42106. return 'Test Runner Finished';
  42107. }
  42108. }
  42109. <?php
  42110. declare (strict_types=1);
  42111. /*
  42112. * This file is part of PHPUnit.
  42113. *
  42114. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42115. *
  42116. * For the full copyright and license information, please view the LICENSE
  42117. * file that was distributed with this source code.
  42118. */
  42119. namespace PHPUnit\Event\TestRunner;
  42120. use PHPUnit\Event\Subscriber;
  42121. /**
  42122. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42123. */
  42124. interface FinishedSubscriber extends Subscriber
  42125. {
  42126. public function notify(\PHPUnit\Event\TestRunner\Finished $event): void;
  42127. }
  42128. <?php
  42129. declare (strict_types=1);
  42130. /*
  42131. * This file is part of PHPUnit.
  42132. *
  42133. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42134. *
  42135. * For the full copyright and license information, please view the LICENSE
  42136. * file that was distributed with this source code.
  42137. */
  42138. namespace PHPUnit\Event\TestRunner;
  42139. use PHPUnit\Event\Event;
  42140. use PHPUnit\Event\Telemetry;
  42141. /**
  42142. * @psalm-immutable
  42143. *
  42144. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42145. */
  42146. final class GarbageCollectionDisabled implements Event
  42147. {
  42148. private readonly Telemetry\Info $telemetryInfo;
  42149. public function __construct(Telemetry\Info $telemetryInfo)
  42150. {
  42151. $this->telemetryInfo = $telemetryInfo;
  42152. }
  42153. public function telemetryInfo(): Telemetry\Info
  42154. {
  42155. return $this->telemetryInfo;
  42156. }
  42157. public function asString(): string
  42158. {
  42159. return 'Test Runner Disabled Garbage Collection';
  42160. }
  42161. }
  42162. <?php
  42163. declare (strict_types=1);
  42164. /*
  42165. * This file is part of PHPUnit.
  42166. *
  42167. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42168. *
  42169. * For the full copyright and license information, please view the LICENSE
  42170. * file that was distributed with this source code.
  42171. */
  42172. namespace PHPUnit\Event\TestRunner;
  42173. use PHPUnit\Event\Subscriber;
  42174. /**
  42175. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42176. */
  42177. interface GarbageCollectionDisabledSubscriber extends Subscriber
  42178. {
  42179. public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionDisabled $event): void;
  42180. }
  42181. <?php
  42182. declare (strict_types=1);
  42183. /*
  42184. * This file is part of PHPUnit.
  42185. *
  42186. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42187. *
  42188. * For the full copyright and license information, please view the LICENSE
  42189. * file that was distributed with this source code.
  42190. */
  42191. namespace PHPUnit\Event\TestRunner;
  42192. use PHPUnit\Event\Event;
  42193. use PHPUnit\Event\Telemetry;
  42194. /**
  42195. * @psalm-immutable
  42196. *
  42197. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42198. */
  42199. final class GarbageCollectionEnabled implements Event
  42200. {
  42201. private readonly Telemetry\Info $telemetryInfo;
  42202. public function __construct(Telemetry\Info $telemetryInfo)
  42203. {
  42204. $this->telemetryInfo = $telemetryInfo;
  42205. }
  42206. public function telemetryInfo(): Telemetry\Info
  42207. {
  42208. return $this->telemetryInfo;
  42209. }
  42210. public function asString(): string
  42211. {
  42212. return 'Test Runner Enabled Garbage Collection';
  42213. }
  42214. }
  42215. <?php
  42216. declare (strict_types=1);
  42217. /*
  42218. * This file is part of PHPUnit.
  42219. *
  42220. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42221. *
  42222. * For the full copyright and license information, please view the LICENSE
  42223. * file that was distributed with this source code.
  42224. */
  42225. namespace PHPUnit\Event\TestRunner;
  42226. use PHPUnit\Event\Subscriber;
  42227. /**
  42228. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42229. */
  42230. interface GarbageCollectionEnabledSubscriber extends Subscriber
  42231. {
  42232. public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionEnabled $event): void;
  42233. }
  42234. <?php
  42235. declare (strict_types=1);
  42236. /*
  42237. * This file is part of PHPUnit.
  42238. *
  42239. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42240. *
  42241. * For the full copyright and license information, please view the LICENSE
  42242. * file that was distributed with this source code.
  42243. */
  42244. namespace PHPUnit\Event\TestRunner;
  42245. use PHPUnit\Event\Event;
  42246. use PHPUnit\Event\Telemetry;
  42247. /**
  42248. * @psalm-immutable
  42249. *
  42250. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42251. */
  42252. final class GarbageCollectionTriggered implements Event
  42253. {
  42254. private readonly Telemetry\Info $telemetryInfo;
  42255. public function __construct(Telemetry\Info $telemetryInfo)
  42256. {
  42257. $this->telemetryInfo = $telemetryInfo;
  42258. }
  42259. public function telemetryInfo(): Telemetry\Info
  42260. {
  42261. return $this->telemetryInfo;
  42262. }
  42263. public function asString(): string
  42264. {
  42265. return 'Test Runner Triggered Garbage Collection';
  42266. }
  42267. }
  42268. <?php
  42269. declare (strict_types=1);
  42270. /*
  42271. * This file is part of PHPUnit.
  42272. *
  42273. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42274. *
  42275. * For the full copyright and license information, please view the LICENSE
  42276. * file that was distributed with this source code.
  42277. */
  42278. namespace PHPUnit\Event\TestRunner;
  42279. use PHPUnit\Event\Subscriber;
  42280. /**
  42281. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42282. */
  42283. interface GarbageCollectionTriggeredSubscriber extends Subscriber
  42284. {
  42285. public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionTriggered $event): void;
  42286. }
  42287. <?php
  42288. declare (strict_types=1);
  42289. /*
  42290. * This file is part of PHPUnit.
  42291. *
  42292. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42293. *
  42294. * For the full copyright and license information, please view the LICENSE
  42295. * file that was distributed with this source code.
  42296. */
  42297. namespace PHPUnit\Event\TestRunner;
  42298. use PHPUnit\Event\Event;
  42299. use PHPUnit\Event\Telemetry;
  42300. /**
  42301. * @psalm-immutable
  42302. *
  42303. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42304. */
  42305. final class Started implements Event
  42306. {
  42307. private readonly Telemetry\Info $telemetryInfo;
  42308. public function __construct(Telemetry\Info $telemetryInfo)
  42309. {
  42310. $this->telemetryInfo = $telemetryInfo;
  42311. }
  42312. public function telemetryInfo(): Telemetry\Info
  42313. {
  42314. return $this->telemetryInfo;
  42315. }
  42316. public function asString(): string
  42317. {
  42318. return 'Test Runner Started';
  42319. }
  42320. }
  42321. <?php
  42322. declare (strict_types=1);
  42323. /*
  42324. * This file is part of PHPUnit.
  42325. *
  42326. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42327. *
  42328. * For the full copyright and license information, please view the LICENSE
  42329. * file that was distributed with this source code.
  42330. */
  42331. namespace PHPUnit\Event\TestRunner;
  42332. use PHPUnit\Event\Subscriber;
  42333. /**
  42334. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42335. */
  42336. interface StartedSubscriber extends Subscriber
  42337. {
  42338. public function notify(\PHPUnit\Event\TestRunner\Started $event): void;
  42339. }
  42340. <?php
  42341. declare (strict_types=1);
  42342. /*
  42343. * This file is part of PHPUnit.
  42344. *
  42345. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42346. *
  42347. * For the full copyright and license information, please view the LICENSE
  42348. * file that was distributed with this source code.
  42349. */
  42350. namespace PHPUnit\Event\TestRunner;
  42351. use function sprintf;
  42352. use PHPUnit\Event\Event;
  42353. use PHPUnit\Event\Telemetry;
  42354. /**
  42355. * @psalm-immutable
  42356. *
  42357. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42358. */
  42359. final class WarningTriggered implements Event
  42360. {
  42361. private readonly Telemetry\Info $telemetryInfo;
  42362. private readonly string $message;
  42363. public function __construct(Telemetry\Info $telemetryInfo, string $message)
  42364. {
  42365. $this->telemetryInfo = $telemetryInfo;
  42366. $this->message = $message;
  42367. }
  42368. public function telemetryInfo(): Telemetry\Info
  42369. {
  42370. return $this->telemetryInfo;
  42371. }
  42372. public function message(): string
  42373. {
  42374. return $this->message;
  42375. }
  42376. public function asString(): string
  42377. {
  42378. return sprintf('Test Runner Triggered Warning (%s)', $this->message);
  42379. }
  42380. }
  42381. <?php
  42382. declare (strict_types=1);
  42383. /*
  42384. * This file is part of PHPUnit.
  42385. *
  42386. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42387. *
  42388. * For the full copyright and license information, please view the LICENSE
  42389. * file that was distributed with this source code.
  42390. */
  42391. namespace PHPUnit\Event\TestRunner;
  42392. use PHPUnit\Event\Subscriber;
  42393. /**
  42394. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42395. */
  42396. interface WarningTriggeredSubscriber extends Subscriber
  42397. {
  42398. public function notify(\PHPUnit\Event\TestRunner\WarningTriggered $event): void;
  42399. }
  42400. <?php
  42401. declare (strict_types=1);
  42402. /*
  42403. * This file is part of PHPUnit.
  42404. *
  42405. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42406. *
  42407. * For the full copyright and license information, please view the LICENSE
  42408. * file that was distributed with this source code.
  42409. */
  42410. namespace PHPUnit\Event\TestSuite;
  42411. use function sprintf;
  42412. use PHPUnit\Event\Event;
  42413. use PHPUnit\Event\Telemetry;
  42414. /**
  42415. * @psalm-immutable
  42416. *
  42417. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42418. */
  42419. final class Filtered implements Event
  42420. {
  42421. private readonly Telemetry\Info $telemetryInfo;
  42422. private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
  42423. public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
  42424. {
  42425. $this->telemetryInfo = $telemetryInfo;
  42426. $this->testSuite = $testSuite;
  42427. }
  42428. public function telemetryInfo(): Telemetry\Info
  42429. {
  42430. return $this->telemetryInfo;
  42431. }
  42432. public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
  42433. {
  42434. return $this->testSuite;
  42435. }
  42436. public function asString(): string
  42437. {
  42438. return sprintf('Test Suite Filtered (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
  42439. }
  42440. }
  42441. <?php
  42442. declare (strict_types=1);
  42443. /*
  42444. * This file is part of PHPUnit.
  42445. *
  42446. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42447. *
  42448. * For the full copyright and license information, please view the LICENSE
  42449. * file that was distributed with this source code.
  42450. */
  42451. namespace PHPUnit\Event\TestSuite;
  42452. use PHPUnit\Event\Subscriber;
  42453. /**
  42454. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42455. */
  42456. interface FilteredSubscriber extends Subscriber
  42457. {
  42458. public function notify(\PHPUnit\Event\TestSuite\Filtered $event): void;
  42459. }
  42460. <?php
  42461. declare (strict_types=1);
  42462. /*
  42463. * This file is part of PHPUnit.
  42464. *
  42465. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42466. *
  42467. * For the full copyright and license information, please view the LICENSE
  42468. * file that was distributed with this source code.
  42469. */
  42470. namespace PHPUnit\Event\TestSuite;
  42471. use function sprintf;
  42472. use PHPUnit\Event\Event;
  42473. use PHPUnit\Event\Telemetry;
  42474. /**
  42475. * @psalm-immutable
  42476. *
  42477. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42478. */
  42479. final class Finished implements Event
  42480. {
  42481. private readonly Telemetry\Info $telemetryInfo;
  42482. private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
  42483. public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
  42484. {
  42485. $this->telemetryInfo = $telemetryInfo;
  42486. $this->testSuite = $testSuite;
  42487. }
  42488. public function telemetryInfo(): Telemetry\Info
  42489. {
  42490. return $this->telemetryInfo;
  42491. }
  42492. public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
  42493. {
  42494. return $this->testSuite;
  42495. }
  42496. public function asString(): string
  42497. {
  42498. return sprintf('Test Suite Finished (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
  42499. }
  42500. }
  42501. <?php
  42502. declare (strict_types=1);
  42503. /*
  42504. * This file is part of PHPUnit.
  42505. *
  42506. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42507. *
  42508. * For the full copyright and license information, please view the LICENSE
  42509. * file that was distributed with this source code.
  42510. */
  42511. namespace PHPUnit\Event\TestSuite;
  42512. use PHPUnit\Event\Subscriber;
  42513. /**
  42514. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42515. */
  42516. interface FinishedSubscriber extends Subscriber
  42517. {
  42518. public function notify(\PHPUnit\Event\TestSuite\Finished $event): void;
  42519. }
  42520. <?php
  42521. declare (strict_types=1);
  42522. /*
  42523. * This file is part of PHPUnit.
  42524. *
  42525. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42526. *
  42527. * For the full copyright and license information, please view the LICENSE
  42528. * file that was distributed with this source code.
  42529. */
  42530. namespace PHPUnit\Event\TestSuite;
  42531. use function sprintf;
  42532. use PHPUnit\Event\Event;
  42533. use PHPUnit\Event\Telemetry;
  42534. /**
  42535. * @psalm-immutable
  42536. *
  42537. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42538. */
  42539. final class Loaded implements Event
  42540. {
  42541. private readonly Telemetry\Info $telemetryInfo;
  42542. private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
  42543. public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
  42544. {
  42545. $this->telemetryInfo = $telemetryInfo;
  42546. $this->testSuite = $testSuite;
  42547. }
  42548. public function telemetryInfo(): Telemetry\Info
  42549. {
  42550. return $this->telemetryInfo;
  42551. }
  42552. public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
  42553. {
  42554. return $this->testSuite;
  42555. }
  42556. public function asString(): string
  42557. {
  42558. return sprintf('Test Suite Loaded (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
  42559. }
  42560. }
  42561. <?php
  42562. declare (strict_types=1);
  42563. /*
  42564. * This file is part of PHPUnit.
  42565. *
  42566. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42567. *
  42568. * For the full copyright and license information, please view the LICENSE
  42569. * file that was distributed with this source code.
  42570. */
  42571. namespace PHPUnit\Event\TestSuite;
  42572. use PHPUnit\Event\Subscriber;
  42573. /**
  42574. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42575. */
  42576. interface LoadedSubscriber extends Subscriber
  42577. {
  42578. public function notify(\PHPUnit\Event\TestSuite\Loaded $event): void;
  42579. }
  42580. <?php
  42581. declare (strict_types=1);
  42582. /*
  42583. * This file is part of PHPUnit.
  42584. *
  42585. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42586. *
  42587. * For the full copyright and license information, please view the LICENSE
  42588. * file that was distributed with this source code.
  42589. */
  42590. namespace PHPUnit\Event\TestSuite;
  42591. use function sprintf;
  42592. use PHPUnit\Event\Event;
  42593. use PHPUnit\Event\Telemetry;
  42594. /**
  42595. * @psalm-immutable
  42596. *
  42597. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42598. */
  42599. final class Skipped implements Event
  42600. {
  42601. private readonly Telemetry\Info $telemetryInfo;
  42602. private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
  42603. private readonly string $message;
  42604. public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite, string $message)
  42605. {
  42606. $this->telemetryInfo = $telemetryInfo;
  42607. $this->testSuite = $testSuite;
  42608. $this->message = $message;
  42609. }
  42610. public function telemetryInfo(): Telemetry\Info
  42611. {
  42612. return $this->telemetryInfo;
  42613. }
  42614. public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
  42615. {
  42616. return $this->testSuite;
  42617. }
  42618. public function message(): string
  42619. {
  42620. return $this->message;
  42621. }
  42622. public function asString(): string
  42623. {
  42624. return sprintf('Test Suite Skipped (%s, %s)', $this->testSuite->name(), $this->message);
  42625. }
  42626. }
  42627. <?php
  42628. declare (strict_types=1);
  42629. /*
  42630. * This file is part of PHPUnit.
  42631. *
  42632. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42633. *
  42634. * For the full copyright and license information, please view the LICENSE
  42635. * file that was distributed with this source code.
  42636. */
  42637. namespace PHPUnit\Event\TestSuite;
  42638. use PHPUnit\Event\Subscriber;
  42639. /**
  42640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42641. */
  42642. interface SkippedSubscriber extends Subscriber
  42643. {
  42644. public function notify(\PHPUnit\Event\TestSuite\Skipped $event): void;
  42645. }
  42646. <?php
  42647. declare (strict_types=1);
  42648. /*
  42649. * This file is part of PHPUnit.
  42650. *
  42651. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42652. *
  42653. * For the full copyright and license information, please view the LICENSE
  42654. * file that was distributed with this source code.
  42655. */
  42656. namespace PHPUnit\Event\TestSuite;
  42657. use PHPUnit\Event\Event;
  42658. use PHPUnit\Event\Telemetry;
  42659. /**
  42660. * @psalm-immutable
  42661. *
  42662. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42663. */
  42664. final class Sorted implements Event
  42665. {
  42666. private readonly Telemetry\Info $telemetryInfo;
  42667. private readonly int $executionOrder;
  42668. private readonly int $executionOrderDefects;
  42669. private readonly bool $resolveDependencies;
  42670. public function __construct(Telemetry\Info $telemetryInfo, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies)
  42671. {
  42672. $this->telemetryInfo = $telemetryInfo;
  42673. $this->executionOrder = $executionOrder;
  42674. $this->executionOrderDefects = $executionOrderDefects;
  42675. $this->resolveDependencies = $resolveDependencies;
  42676. }
  42677. public function telemetryInfo(): Telemetry\Info
  42678. {
  42679. return $this->telemetryInfo;
  42680. }
  42681. public function executionOrder(): int
  42682. {
  42683. return $this->executionOrder;
  42684. }
  42685. public function executionOrderDefects(): int
  42686. {
  42687. return $this->executionOrderDefects;
  42688. }
  42689. public function resolveDependencies(): bool
  42690. {
  42691. return $this->resolveDependencies;
  42692. }
  42693. public function asString(): string
  42694. {
  42695. return 'Test Suite Sorted';
  42696. }
  42697. }
  42698. <?php
  42699. declare (strict_types=1);
  42700. /*
  42701. * This file is part of PHPUnit.
  42702. *
  42703. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42704. *
  42705. * For the full copyright and license information, please view the LICENSE
  42706. * file that was distributed with this source code.
  42707. */
  42708. namespace PHPUnit\Event\TestSuite;
  42709. use PHPUnit\Event\Subscriber;
  42710. /**
  42711. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42712. */
  42713. interface SortedSubscriber extends Subscriber
  42714. {
  42715. public function notify(\PHPUnit\Event\TestSuite\Sorted $event): void;
  42716. }
  42717. <?php
  42718. declare (strict_types=1);
  42719. /*
  42720. * This file is part of PHPUnit.
  42721. *
  42722. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42723. *
  42724. * For the full copyright and license information, please view the LICENSE
  42725. * file that was distributed with this source code.
  42726. */
  42727. namespace PHPUnit\Event\TestSuite;
  42728. use function sprintf;
  42729. use PHPUnit\Event\Event;
  42730. use PHPUnit\Event\Telemetry;
  42731. /**
  42732. * @psalm-immutable
  42733. *
  42734. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42735. */
  42736. final class Started implements Event
  42737. {
  42738. private readonly Telemetry\Info $telemetryInfo;
  42739. private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
  42740. public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
  42741. {
  42742. $this->telemetryInfo = $telemetryInfo;
  42743. $this->testSuite = $testSuite;
  42744. }
  42745. public function telemetryInfo(): Telemetry\Info
  42746. {
  42747. return $this->telemetryInfo;
  42748. }
  42749. public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
  42750. {
  42751. return $this->testSuite;
  42752. }
  42753. public function asString(): string
  42754. {
  42755. return sprintf('Test Suite Started (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
  42756. }
  42757. }
  42758. <?php
  42759. declare (strict_types=1);
  42760. /*
  42761. * This file is part of PHPUnit.
  42762. *
  42763. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42764. *
  42765. * For the full copyright and license information, please view the LICENSE
  42766. * file that was distributed with this source code.
  42767. */
  42768. namespace PHPUnit\Event\TestSuite;
  42769. use PHPUnit\Event\Subscriber;
  42770. /**
  42771. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42772. */
  42773. interface StartedSubscriber extends Subscriber
  42774. {
  42775. public function notify(\PHPUnit\Event\TestSuite\Started $event): void;
  42776. }
  42777. <?php
  42778. declare (strict_types=1);
  42779. /*
  42780. * This file is part of PHPUnit.
  42781. *
  42782. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42783. *
  42784. * For the full copyright and license information, please view the LICENSE
  42785. * file that was distributed with this source code.
  42786. */
  42787. namespace PHPUnit\Event;
  42788. use RuntimeException;
  42789. /**
  42790. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42791. */
  42792. final class EventAlreadyAssignedException extends RuntimeException implements \PHPUnit\Event\Exception
  42793. {
  42794. }
  42795. <?php
  42796. declare (strict_types=1);
  42797. /*
  42798. * This file is part of PHPUnit.
  42799. *
  42800. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42801. *
  42802. * For the full copyright and license information, please view the LICENSE
  42803. * file that was distributed with this source code.
  42804. */
  42805. namespace PHPUnit\Event;
  42806. use RuntimeException;
  42807. /**
  42808. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42809. */
  42810. final class EventFacadeIsSealedException extends RuntimeException implements \PHPUnit\Event\Exception
  42811. {
  42812. }
  42813. <?php
  42814. declare (strict_types=1);
  42815. /*
  42816. * This file is part of PHPUnit.
  42817. *
  42818. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42819. *
  42820. * For the full copyright and license information, please view the LICENSE
  42821. * file that was distributed with this source code.
  42822. */
  42823. namespace PHPUnit\Event;
  42824. interface Exception extends \PHPUnit\Exception
  42825. {
  42826. }
  42827. <?php
  42828. declare (strict_types=1);
  42829. /*
  42830. * This file is part of PHPUnit.
  42831. *
  42832. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42833. *
  42834. * For the full copyright and license information, please view the LICENSE
  42835. * file that was distributed with this source code.
  42836. */
  42837. namespace PHPUnit\Event;
  42838. /**
  42839. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42840. */
  42841. final class InvalidArgumentException extends \InvalidArgumentException implements \PHPUnit\Event\Exception
  42842. {
  42843. }
  42844. <?php
  42845. declare (strict_types=1);
  42846. /*
  42847. * This file is part of PHPUnit.
  42848. *
  42849. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42850. *
  42851. * For the full copyright and license information, please view the LICENSE
  42852. * file that was distributed with this source code.
  42853. */
  42854. namespace PHPUnit\Event;
  42855. use RuntimeException;
  42856. /**
  42857. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42858. */
  42859. final class InvalidEventException extends RuntimeException implements \PHPUnit\Event\Exception
  42860. {
  42861. }
  42862. <?php
  42863. declare (strict_types=1);
  42864. /*
  42865. * This file is part of PHPUnit.
  42866. *
  42867. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42868. *
  42869. * For the full copyright and license information, please view the LICENSE
  42870. * file that was distributed with this source code.
  42871. */
  42872. namespace PHPUnit\Event;
  42873. use RuntimeException;
  42874. /**
  42875. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42876. */
  42877. final class InvalidSubscriberException extends RuntimeException implements \PHPUnit\Event\Exception
  42878. {
  42879. }
  42880. <?php
  42881. declare (strict_types=1);
  42882. /*
  42883. * This file is part of PHPUnit.
  42884. *
  42885. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42886. *
  42887. * For the full copyright and license information, please view the LICENSE
  42888. * file that was distributed with this source code.
  42889. */
  42890. namespace PHPUnit\Event;
  42891. use RuntimeException;
  42892. /**
  42893. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42894. */
  42895. final class MapError extends RuntimeException implements \PHPUnit\Event\Exception
  42896. {
  42897. }
  42898. <?php
  42899. declare (strict_types=1);
  42900. /*
  42901. * This file is part of PHPUnit.
  42902. *
  42903. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42904. *
  42905. * For the full copyright and license information, please view the LICENSE
  42906. * file that was distributed with this source code.
  42907. */
  42908. namespace PHPUnit\Event\TestData;
  42909. use PHPUnit\Event\Exception;
  42910. use RuntimeException;
  42911. /**
  42912. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42913. */
  42914. final class MoreThanOneDataSetFromDataProviderException extends RuntimeException implements Exception
  42915. {
  42916. }
  42917. <?php
  42918. declare (strict_types=1);
  42919. /*
  42920. * This file is part of PHPUnit.
  42921. *
  42922. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42923. *
  42924. * For the full copyright and license information, please view the LICENSE
  42925. * file that was distributed with this source code.
  42926. */
  42927. namespace PHPUnit\Event\Test;
  42928. use PHPUnit\Event\Exception;
  42929. use RuntimeException;
  42930. /**
  42931. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42932. */
  42933. final class NoComparisonFailureException extends RuntimeException implements Exception
  42934. {
  42935. }
  42936. <?php
  42937. declare (strict_types=1);
  42938. /*
  42939. * This file is part of PHPUnit.
  42940. *
  42941. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42942. *
  42943. * For the full copyright and license information, please view the LICENSE
  42944. * file that was distributed with this source code.
  42945. */
  42946. namespace PHPUnit\Event\TestData;
  42947. use PHPUnit\Event\Exception;
  42948. use RuntimeException;
  42949. /**
  42950. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42951. */
  42952. final class NoDataSetFromDataProviderException extends RuntimeException implements Exception
  42953. {
  42954. }
  42955. <?php
  42956. declare (strict_types=1);
  42957. /*
  42958. * This file is part of PHPUnit.
  42959. *
  42960. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42961. *
  42962. * For the full copyright and license information, please view the LICENSE
  42963. * file that was distributed with this source code.
  42964. */
  42965. namespace PHPUnit\Event;
  42966. use RuntimeException;
  42967. /**
  42968. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42969. */
  42970. final class NoPreviousThrowableException extends RuntimeException implements \PHPUnit\Event\Exception
  42971. {
  42972. }
  42973. <?php
  42974. declare (strict_types=1);
  42975. /*
  42976. * This file is part of PHPUnit.
  42977. *
  42978. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  42979. *
  42980. * For the full copyright and license information, please view the LICENSE
  42981. * file that was distributed with this source code.
  42982. */
  42983. namespace PHPUnit\Event\Code;
  42984. use PHPUnit\Event\Exception;
  42985. use RuntimeException;
  42986. /**
  42987. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  42988. *
  42989. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  42990. */
  42991. final class NoTestCaseObjectOnCallStackException extends RuntimeException implements Exception
  42992. {
  42993. public function __construct()
  42994. {
  42995. parent::__construct('Cannot find TestCase object on call stack');
  42996. }
  42997. }
  42998. <?php
  42999. declare (strict_types=1);
  43000. /*
  43001. * This file is part of PHPUnit.
  43002. *
  43003. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43004. *
  43005. * For the full copyright and license information, please view the LICENSE
  43006. * file that was distributed with this source code.
  43007. */
  43008. namespace PHPUnit\Event;
  43009. /**
  43010. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43011. */
  43012. final class RuntimeException extends \RuntimeException implements \PHPUnit\Event\Exception
  43013. {
  43014. }
  43015. <?php
  43016. declare (strict_types=1);
  43017. /*
  43018. * This file is part of PHPUnit.
  43019. *
  43020. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43021. *
  43022. * For the full copyright and license information, please view the LICENSE
  43023. * file that was distributed with this source code.
  43024. */
  43025. namespace PHPUnit\Event;
  43026. use RuntimeException;
  43027. /**
  43028. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43029. */
  43030. final class SubscriberTypeAlreadyRegisteredException extends RuntimeException implements \PHPUnit\Event\Exception
  43031. {
  43032. }
  43033. <?php
  43034. declare (strict_types=1);
  43035. /*
  43036. * This file is part of PHPUnit.
  43037. *
  43038. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43039. *
  43040. * For the full copyright and license information, please view the LICENSE
  43041. * file that was distributed with this source code.
  43042. */
  43043. namespace PHPUnit\Event;
  43044. use RuntimeException;
  43045. /**
  43046. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43047. */
  43048. final class UnknownEventException extends RuntimeException implements \PHPUnit\Event\Exception
  43049. {
  43050. }
  43051. <?php
  43052. declare (strict_types=1);
  43053. /*
  43054. * This file is part of PHPUnit.
  43055. *
  43056. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43057. *
  43058. * For the full copyright and license information, please view the LICENSE
  43059. * file that was distributed with this source code.
  43060. */
  43061. namespace PHPUnit\Event;
  43062. use RuntimeException;
  43063. /**
  43064. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43065. */
  43066. final class UnknownEventTypeException extends RuntimeException implements \PHPUnit\Event\Exception
  43067. {
  43068. }
  43069. <?php
  43070. declare (strict_types=1);
  43071. /*
  43072. * This file is part of PHPUnit.
  43073. *
  43074. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43075. *
  43076. * For the full copyright and license information, please view the LICENSE
  43077. * file that was distributed with this source code.
  43078. */
  43079. namespace PHPUnit\Event;
  43080. use RuntimeException;
  43081. /**
  43082. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43083. */
  43084. final class UnknownSubscriberException extends RuntimeException implements \PHPUnit\Event\Exception
  43085. {
  43086. }
  43087. <?php
  43088. declare (strict_types=1);
  43089. /*
  43090. * This file is part of PHPUnit.
  43091. *
  43092. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43093. *
  43094. * For the full copyright and license information, please view the LICENSE
  43095. * file that was distributed with this source code.
  43096. */
  43097. namespace PHPUnit\Event;
  43098. use RuntimeException;
  43099. /**
  43100. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43101. */
  43102. final class UnknownSubscriberTypeException extends RuntimeException implements \PHPUnit\Event\Exception
  43103. {
  43104. }
  43105. <?php
  43106. declare (strict_types=1);
  43107. /*
  43108. * This file is part of PHPUnit.
  43109. *
  43110. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43111. *
  43112. * For the full copyright and license information, please view the LICENSE
  43113. * file that was distributed with this source code.
  43114. */
  43115. namespace PHPUnit\Event;
  43116. use function gc_status;
  43117. use PHPUnit\Event\Telemetry\HRTime;
  43118. use PHPUnit\Event\Telemetry\Php81GarbageCollectorStatusProvider;
  43119. use PHPUnit\Event\Telemetry\Php83GarbageCollectorStatusProvider;
  43120. /**
  43121. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43122. *
  43123. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  43124. */
  43125. final class Facade
  43126. {
  43127. private static ?self $instance = null;
  43128. private \PHPUnit\Event\Emitter $emitter;
  43129. private ?\PHPUnit\Event\TypeMap $typeMap = null;
  43130. private ?\PHPUnit\Event\DeferringDispatcher $deferringDispatcher = null;
  43131. private bool $sealed = \false;
  43132. public static function instance(): self
  43133. {
  43134. if (self::$instance === null) {
  43135. self::$instance = new self();
  43136. }
  43137. return self::$instance;
  43138. }
  43139. public static function emitter(): \PHPUnit\Event\Emitter
  43140. {
  43141. return self::instance()->emitter;
  43142. }
  43143. public function __construct()
  43144. {
  43145. $this->emitter = $this->createDispatchingEmitter();
  43146. }
  43147. /**
  43148. * @throws EventFacadeIsSealedException
  43149. * @throws UnknownSubscriberTypeException
  43150. */
  43151. public function registerSubscribers(\PHPUnit\Event\Subscriber ...$subscribers): void
  43152. {
  43153. foreach ($subscribers as $subscriber) {
  43154. $this->registerSubscriber($subscriber);
  43155. }
  43156. }
  43157. /**
  43158. * @throws EventFacadeIsSealedException
  43159. * @throws UnknownSubscriberTypeException
  43160. */
  43161. public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
  43162. {
  43163. if ($this->sealed) {
  43164. throw new \PHPUnit\Event\EventFacadeIsSealedException();
  43165. }
  43166. $this->deferredDispatcher()->registerSubscriber($subscriber);
  43167. }
  43168. /**
  43169. * @throws EventFacadeIsSealedException
  43170. */
  43171. public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
  43172. {
  43173. if ($this->sealed) {
  43174. throw new \PHPUnit\Event\EventFacadeIsSealedException();
  43175. }
  43176. $this->deferredDispatcher()->registerTracer($tracer);
  43177. }
  43178. /**
  43179. * @codeCoverageIgnore
  43180. *
  43181. * @noinspection PhpUnused
  43182. */
  43183. public function initForIsolation(HRTime $offset, bool $exportObjects): \PHPUnit\Event\CollectingDispatcher
  43184. {
  43185. $dispatcher = new \PHPUnit\Event\CollectingDispatcher();
  43186. $this->emitter = new \PHPUnit\Event\DispatchingEmitter($dispatcher, new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatchWithOffset($offset), new \PHPUnit\Event\Telemetry\SystemMemoryMeter(), $this->garbageCollectorStatusProvider()));
  43187. if ($exportObjects) {
  43188. $this->emitter->exportObjects();
  43189. }
  43190. $this->sealed = \true;
  43191. return $dispatcher;
  43192. }
  43193. public function forward(\PHPUnit\Event\EventCollection $events): void
  43194. {
  43195. $dispatcher = $this->deferredDispatcher();
  43196. foreach ($events as $event) {
  43197. $dispatcher->dispatch($event);
  43198. }
  43199. }
  43200. public function seal(): void
  43201. {
  43202. $this->deferredDispatcher()->flush();
  43203. $this->sealed = \true;
  43204. $this->emitter->testRunnerEventFacadeSealed();
  43205. }
  43206. private function createDispatchingEmitter(): \PHPUnit\Event\DispatchingEmitter
  43207. {
  43208. return new \PHPUnit\Event\DispatchingEmitter($this->deferredDispatcher(), $this->createTelemetrySystem());
  43209. }
  43210. private function createTelemetrySystem(): \PHPUnit\Event\Telemetry\System
  43211. {
  43212. return new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatch(), new \PHPUnit\Event\Telemetry\SystemMemoryMeter(), $this->garbageCollectorStatusProvider());
  43213. }
  43214. private function deferredDispatcher(): \PHPUnit\Event\DeferringDispatcher
  43215. {
  43216. if ($this->deferringDispatcher === null) {
  43217. $this->deferringDispatcher = new \PHPUnit\Event\DeferringDispatcher(new \PHPUnit\Event\DirectDispatcher($this->typeMap()));
  43218. }
  43219. return $this->deferringDispatcher;
  43220. }
  43221. private function typeMap(): \PHPUnit\Event\TypeMap
  43222. {
  43223. if ($this->typeMap === null) {
  43224. $typeMap = new \PHPUnit\Event\TypeMap();
  43225. $this->registerDefaultTypes($typeMap);
  43226. $this->typeMap = $typeMap;
  43227. }
  43228. return $this->typeMap;
  43229. }
  43230. private function registerDefaultTypes(\PHPUnit\Event\TypeMap $typeMap): void
  43231. {
  43232. $defaultEvents = [\PHPUnit\Event\Application\Started::class, \PHPUnit\Event\Application\Finished::class, \PHPUnit\Event\Test\DataProviderMethodCalled::class, \PHPUnit\Event\Test\DataProviderMethodFinished::class, \PHPUnit\Event\Test\MarkedIncomplete::class, \PHPUnit\Event\Test\AfterLastTestMethodCalled::class, \PHPUnit\Event\Test\AfterLastTestMethodFinished::class, \PHPUnit\Event\Test\AfterTestMethodCalled::class, \PHPUnit\Event\Test\AfterTestMethodFinished::class, \PHPUnit\Event\Test\AssertionSucceeded::class, \PHPUnit\Event\Test\AssertionFailed::class, \PHPUnit\Event\Test\BeforeFirstTestMethodCalled::class, \PHPUnit\Event\Test\BeforeFirstTestMethodErrored::class, \PHPUnit\Event\Test\BeforeFirstTestMethodFinished::class, \PHPUnit\Event\Test\BeforeTestMethodCalled::class, \PHPUnit\Event\Test\BeforeTestMethodFinished::class, \PHPUnit\Event\Test\ComparatorRegistered::class, \PHPUnit\Event\Test\ConsideredRisky::class, \PHPUnit\Event\Test\DeprecationTriggered::class, \PHPUnit\Event\Test\Errored::class, \PHPUnit\Event\Test\ErrorTriggered::class, \PHPUnit\Event\Test\Failed::class, \PHPUnit\Event\Test\Finished::class, \PHPUnit\Event\Test\NoticeTriggered::class, \PHPUnit\Event\Test\Passed::class, \PHPUnit\Event\Test\PhpDeprecationTriggered::class, \PHPUnit\Event\Test\PhpNoticeTriggered::class, \PHPUnit\Event\Test\PhpunitDeprecationTriggered::class, \PHPUnit\Event\Test\PhpunitErrorTriggered::class, \PHPUnit\Event\Test\PhpunitWarningTriggered::class, \PHPUnit\Event\Test\PhpWarningTriggered::class, \PHPUnit\Event\Test\PostConditionCalled::class, \PHPUnit\Event\Test\PostConditionFinished::class, \PHPUnit\Event\Test\PreConditionCalled::class, \PHPUnit\Event\Test\PreConditionFinished::class, \PHPUnit\Event\Test\PreparationStarted::class, \PHPUnit\Event\Test\Prepared::class, \PHPUnit\Event\Test\PreparationFailed::class, \PHPUnit\Event\Test\PrintedUnexpectedOutput::class, \PHPUnit\Event\Test\Skipped::class, \PHPUnit\Event\Test\WarningTriggered::class, \PHPUnit\Event\Test\MockObjectCreated::class, \PHPUnit\Event\Test\MockObjectForAbstractClassCreated::class, \PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\Test\MockObjectForTraitCreated::class, \PHPUnit\Event\Test\MockObjectFromWsdlCreated::class, \PHPUnit\Event\Test\PartialMockObjectCreated::class, \PHPUnit\Event\Test\TestProxyCreated::class, \PHPUnit\Event\Test\TestStubCreated::class, \PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\TestRunner\BootstrapFinished::class, \PHPUnit\Event\TestRunner\Configured::class, \PHPUnit\Event\TestRunner\EventFacadeSealed::class, \PHPUnit\Event\TestRunner\ExecutionAborted::class, \PHPUnit\Event\TestRunner\ExecutionFinished::class, \PHPUnit\Event\TestRunner\ExecutionStarted::class, \PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar::class, \PHPUnit\Event\TestRunner\ExtensionBootstrapped::class, \PHPUnit\Event\TestRunner\Finished::class, \PHPUnit\Event\TestRunner\Started::class, \PHPUnit\Event\TestRunner\DeprecationTriggered::class, \PHPUnit\Event\TestRunner\WarningTriggered::class, \PHPUnit\Event\TestRunner\GarbageCollectionDisabled::class, \PHPUnit\Event\TestRunner\GarbageCollectionTriggered::class, \PHPUnit\Event\TestRunner\GarbageCollectionEnabled::class, \PHPUnit\Event\TestSuite\Filtered::class, \PHPUnit\Event\TestSuite\Finished::class, \PHPUnit\Event\TestSuite\Loaded::class, \PHPUnit\Event\TestSuite\Skipped::class, \PHPUnit\Event\TestSuite\Sorted::class, \PHPUnit\Event\TestSuite\Started::class];
  43233. foreach ($defaultEvents as $eventClass) {
  43234. $typeMap->addMapping($eventClass . 'Subscriber', $eventClass);
  43235. }
  43236. }
  43237. private function garbageCollectorStatusProvider(): \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
  43238. {
  43239. if (!isset(gc_status()['running'])) {
  43240. // @codeCoverageIgnoreStart
  43241. return new Php81GarbageCollectorStatusProvider();
  43242. // @codeCoverageIgnoreEnd
  43243. }
  43244. return new Php83GarbageCollectorStatusProvider();
  43245. }
  43246. }
  43247. <?php
  43248. declare (strict_types=1);
  43249. /*
  43250. * This file is part of PHPUnit.
  43251. *
  43252. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43253. *
  43254. * For the full copyright and license information, please view the LICENSE
  43255. * file that was distributed with this source code.
  43256. */
  43257. namespace PHPUnit\Event;
  43258. /**
  43259. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43260. */
  43261. interface Subscriber
  43262. {
  43263. }
  43264. <?php
  43265. declare (strict_types=1);
  43266. /*
  43267. * This file is part of PHPUnit.
  43268. *
  43269. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43270. *
  43271. * For the full copyright and license information, please view the LICENSE
  43272. * file that was distributed with this source code.
  43273. */
  43274. namespace PHPUnit\Event\Tracer;
  43275. use PHPUnit\Event\Event;
  43276. /**
  43277. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43278. */
  43279. interface Tracer
  43280. {
  43281. public function trace(Event $event): void;
  43282. }
  43283. <?php
  43284. declare (strict_types=1);
  43285. /*
  43286. * This file is part of PHPUnit.
  43287. *
  43288. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43289. *
  43290. * For the full copyright and license information, please view the LICENSE
  43291. * file that was distributed with this source code.
  43292. */
  43293. namespace PHPUnit\Event;
  43294. use function array_key_exists;
  43295. use function class_exists;
  43296. use function class_implements;
  43297. use function in_array;
  43298. use function interface_exists;
  43299. use function sprintf;
  43300. /**
  43301. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43302. *
  43303. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  43304. */
  43305. final class TypeMap
  43306. {
  43307. /**
  43308. * @psalm-var array<class-string, class-string>
  43309. */
  43310. private array $mapping = [];
  43311. /**
  43312. * @psalm-param class-string $subscriberInterface
  43313. * @psalm-param class-string $eventClass
  43314. *
  43315. * @throws EventAlreadyAssignedException
  43316. * @throws InvalidEventException
  43317. * @throws InvalidSubscriberException
  43318. * @throws SubscriberTypeAlreadyRegisteredException
  43319. * @throws UnknownEventException
  43320. * @throws UnknownSubscriberException
  43321. */
  43322. public function addMapping(string $subscriberInterface, string $eventClass): void
  43323. {
  43324. $this->ensureSubscriberInterfaceExists($subscriberInterface);
  43325. $this->ensureSubscriberInterfaceExtendsInterface($subscriberInterface);
  43326. $this->ensureEventClassExists($eventClass);
  43327. $this->ensureEventClassImplementsEventInterface($eventClass);
  43328. $this->ensureSubscriberWasNotAlreadyRegistered($subscriberInterface);
  43329. $this->ensureEventWasNotAlreadyAssigned($eventClass);
  43330. $this->mapping[$subscriberInterface] = $eventClass;
  43331. }
  43332. public function isKnownSubscriberType(\PHPUnit\Event\Subscriber $subscriber): bool
  43333. {
  43334. foreach (class_implements($subscriber) as $interface) {
  43335. if (array_key_exists($interface, $this->mapping)) {
  43336. return \true;
  43337. }
  43338. }
  43339. return \false;
  43340. }
  43341. public function isKnownEventType(\PHPUnit\Event\Event $event): bool
  43342. {
  43343. return in_array($event::class, $this->mapping, \true);
  43344. }
  43345. /**
  43346. * @psalm-return class-string
  43347. *
  43348. * @throws MapError
  43349. */
  43350. public function map(\PHPUnit\Event\Subscriber $subscriber): string
  43351. {
  43352. foreach (class_implements($subscriber) as $interface) {
  43353. if (array_key_exists($interface, $this->mapping)) {
  43354. return $this->mapping[$interface];
  43355. }
  43356. }
  43357. throw new \PHPUnit\Event\MapError(sprintf('Subscriber "%s" does not implement a known interface', $subscriber::class));
  43358. }
  43359. /**
  43360. * @psalm-param class-string $subscriberInterface
  43361. *
  43362. * @throws UnknownSubscriberException
  43363. */
  43364. private function ensureSubscriberInterfaceExists(string $subscriberInterface): void
  43365. {
  43366. if (!interface_exists($subscriberInterface)) {
  43367. throw new \PHPUnit\Event\UnknownSubscriberException(sprintf('Subscriber "%s" does not exist or is not an interface', $subscriberInterface));
  43368. }
  43369. }
  43370. /**
  43371. * @psalm-param class-string $eventClass
  43372. *
  43373. * @throws UnknownEventException
  43374. */
  43375. private function ensureEventClassExists(string $eventClass): void
  43376. {
  43377. if (!class_exists($eventClass)) {
  43378. throw new \PHPUnit\Event\UnknownEventException(sprintf('Event class "%s" does not exist', $eventClass));
  43379. }
  43380. }
  43381. /**
  43382. * @psalm-param class-string $subscriberInterface
  43383. *
  43384. * @throws InvalidSubscriberException
  43385. */
  43386. private function ensureSubscriberInterfaceExtendsInterface(string $subscriberInterface): void
  43387. {
  43388. if (!in_array(\PHPUnit\Event\Subscriber::class, class_implements($subscriberInterface), \true)) {
  43389. throw new \PHPUnit\Event\InvalidSubscriberException(sprintf('Subscriber "%s" does not extend Subscriber interface', $subscriberInterface));
  43390. }
  43391. }
  43392. /**
  43393. * @psalm-param class-string $eventClass
  43394. *
  43395. * @throws InvalidEventException
  43396. */
  43397. private function ensureEventClassImplementsEventInterface(string $eventClass): void
  43398. {
  43399. if (!in_array(\PHPUnit\Event\Event::class, class_implements($eventClass), \true)) {
  43400. throw new \PHPUnit\Event\InvalidEventException(sprintf('Event "%s" does not implement Event interface', $eventClass));
  43401. }
  43402. }
  43403. /**
  43404. * @psalm-param class-string $subscriberInterface
  43405. *
  43406. * @throws SubscriberTypeAlreadyRegisteredException
  43407. */
  43408. private function ensureSubscriberWasNotAlreadyRegistered(string $subscriberInterface): void
  43409. {
  43410. if (array_key_exists($subscriberInterface, $this->mapping)) {
  43411. throw new \PHPUnit\Event\SubscriberTypeAlreadyRegisteredException(sprintf('Subscriber type "%s" already registered', $subscriberInterface));
  43412. }
  43413. }
  43414. /**
  43415. * @psalm-param class-string $eventClass
  43416. *
  43417. * @throws EventAlreadyAssignedException
  43418. */
  43419. private function ensureEventWasNotAlreadyAssigned(string $eventClass): void
  43420. {
  43421. if (in_array($eventClass, $this->mapping, \true)) {
  43422. throw new \PHPUnit\Event\EventAlreadyAssignedException(sprintf('Event "%s" already assigned', $eventClass));
  43423. }
  43424. }
  43425. }
  43426. <?php
  43427. declare (strict_types=1);
  43428. /*
  43429. * This file is part of PHPUnit.
  43430. *
  43431. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43432. *
  43433. * For the full copyright and license information, please view the LICENSE
  43434. * file that was distributed with this source code.
  43435. */
  43436. namespace PHPUnit\Event\Code;
  43437. /**
  43438. * @psalm-immutable
  43439. *
  43440. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43441. */
  43442. final class ClassMethod
  43443. {
  43444. /**
  43445. * @psalm-var class-string
  43446. */
  43447. private readonly string $className;
  43448. /**
  43449. * @psalm-var non-empty-string
  43450. */
  43451. private readonly string $methodName;
  43452. /**
  43453. * @psalm-param class-string $className
  43454. * @psalm-param non-empty-string $methodName
  43455. */
  43456. public function __construct(string $className, string $methodName)
  43457. {
  43458. $this->className = $className;
  43459. $this->methodName = $methodName;
  43460. }
  43461. /**
  43462. * @psalm-return class-string
  43463. */
  43464. public function className(): string
  43465. {
  43466. return $this->className;
  43467. }
  43468. /**
  43469. * @psalm-return non-empty-string
  43470. */
  43471. public function methodName(): string
  43472. {
  43473. return $this->methodName;
  43474. }
  43475. }
  43476. <?php
  43477. declare (strict_types=1);
  43478. /*
  43479. * This file is part of PHPUnit.
  43480. *
  43481. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43482. *
  43483. * For the full copyright and license information, please view the LICENSE
  43484. * file that was distributed with this source code.
  43485. */
  43486. namespace PHPUnit\Event\Code;
  43487. /**
  43488. * @psalm-immutable
  43489. *
  43490. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43491. */
  43492. final class ComparisonFailure
  43493. {
  43494. private readonly string $expected;
  43495. private readonly string $actual;
  43496. private readonly string $diff;
  43497. public function __construct(string $expected, string $actual, string $diff)
  43498. {
  43499. $this->expected = $expected;
  43500. $this->actual = $actual;
  43501. $this->diff = $diff;
  43502. }
  43503. public function expected(): string
  43504. {
  43505. return $this->expected;
  43506. }
  43507. public function actual(): string
  43508. {
  43509. return $this->actual;
  43510. }
  43511. public function diff(): string
  43512. {
  43513. return $this->diff;
  43514. }
  43515. }
  43516. <?php
  43517. declare (strict_types=1);
  43518. /*
  43519. * This file is part of PHPUnit.
  43520. *
  43521. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43522. *
  43523. * For the full copyright and license information, please view the LICENSE
  43524. * file that was distributed with this source code.
  43525. */
  43526. namespace PHPUnit\Event\Code;
  43527. use function is_bool;
  43528. use function is_scalar;
  43529. use function print_r;
  43530. use PHPUnit\Framework\ExpectationFailedException;
  43531. use Throwable;
  43532. /**
  43533. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43534. *
  43535. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  43536. */
  43537. final class ComparisonFailureBuilder
  43538. {
  43539. public static function from(Throwable $t): ?\PHPUnit\Event\Code\ComparisonFailure
  43540. {
  43541. if (!$t instanceof ExpectationFailedException) {
  43542. return null;
  43543. }
  43544. if (!$t->getComparisonFailure()) {
  43545. return null;
  43546. }
  43547. $expectedAsString = $t->getComparisonFailure()->getExpectedAsString();
  43548. if (empty($expectedAsString)) {
  43549. $expectedAsString = self::mapScalarValueToString($t->getComparisonFailure()->getExpected());
  43550. }
  43551. $actualAsString = $t->getComparisonFailure()->getActualAsString();
  43552. if (empty($actualAsString)) {
  43553. $actualAsString = self::mapScalarValueToString($t->getComparisonFailure()->getActual());
  43554. }
  43555. return new \PHPUnit\Event\Code\ComparisonFailure($expectedAsString, $actualAsString, $t->getComparisonFailure()->getDiff());
  43556. }
  43557. private static function mapScalarValueToString(mixed $value): string
  43558. {
  43559. if ($value === null) {
  43560. return 'null';
  43561. }
  43562. if (is_bool($value)) {
  43563. return $value ? 'true' : 'false';
  43564. }
  43565. if (is_scalar($value)) {
  43566. return print_r($value, \true);
  43567. }
  43568. return '';
  43569. }
  43570. }
  43571. <?php
  43572. declare (strict_types=1);
  43573. /*
  43574. * This file is part of PHPUnit.
  43575. *
  43576. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43577. *
  43578. * For the full copyright and license information, please view the LICENSE
  43579. * file that was distributed with this source code.
  43580. */
  43581. namespace PHPUnit\Event\Runtime;
  43582. use const PHP_OS;
  43583. use const PHP_OS_FAMILY;
  43584. /**
  43585. * @psalm-immutable
  43586. *
  43587. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43588. */
  43589. final class OperatingSystem
  43590. {
  43591. private readonly string $operatingSystem;
  43592. private readonly string $operatingSystemFamily;
  43593. public function __construct()
  43594. {
  43595. $this->operatingSystem = PHP_OS;
  43596. $this->operatingSystemFamily = PHP_OS_FAMILY;
  43597. }
  43598. public function operatingSystem(): string
  43599. {
  43600. return $this->operatingSystem;
  43601. }
  43602. public function operatingSystemFamily(): string
  43603. {
  43604. return $this->operatingSystemFamily;
  43605. }
  43606. }
  43607. <?php
  43608. declare (strict_types=1);
  43609. /*
  43610. * This file is part of PHPUnit.
  43611. *
  43612. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43613. *
  43614. * For the full copyright and license information, please view the LICENSE
  43615. * file that was distributed with this source code.
  43616. */
  43617. namespace PHPUnit\Event\Runtime;
  43618. use const PHP_EXTRA_VERSION;
  43619. use const PHP_MAJOR_VERSION;
  43620. use const PHP_MINOR_VERSION;
  43621. use const PHP_RELEASE_VERSION;
  43622. use const PHP_SAPI;
  43623. use const PHP_VERSION;
  43624. use const PHP_VERSION_ID;
  43625. use function array_merge;
  43626. use function get_loaded_extensions;
  43627. use function sort;
  43628. /**
  43629. * @psalm-immutable
  43630. *
  43631. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43632. */
  43633. final class PHP
  43634. {
  43635. private readonly string $version;
  43636. private readonly int $versionId;
  43637. private readonly int $majorVersion;
  43638. private readonly int $minorVersion;
  43639. private readonly int $releaseVersion;
  43640. private readonly string $extraVersion;
  43641. private readonly string $sapi;
  43642. /**
  43643. * @psalm-var list<string>
  43644. */
  43645. private readonly array $extensions;
  43646. public function __construct()
  43647. {
  43648. $this->version = PHP_VERSION;
  43649. $this->versionId = PHP_VERSION_ID;
  43650. $this->majorVersion = PHP_MAJOR_VERSION;
  43651. $this->minorVersion = PHP_MINOR_VERSION;
  43652. $this->releaseVersion = PHP_RELEASE_VERSION;
  43653. $this->extraVersion = PHP_EXTRA_VERSION;
  43654. $this->sapi = PHP_SAPI;
  43655. $extensions = array_merge(get_loaded_extensions(\true), get_loaded_extensions());
  43656. sort($extensions);
  43657. $this->extensions = $extensions;
  43658. }
  43659. public function version(): string
  43660. {
  43661. return $this->version;
  43662. }
  43663. public function sapi(): string
  43664. {
  43665. return $this->sapi;
  43666. }
  43667. public function majorVersion(): int
  43668. {
  43669. return $this->majorVersion;
  43670. }
  43671. public function minorVersion(): int
  43672. {
  43673. return $this->minorVersion;
  43674. }
  43675. public function releaseVersion(): int
  43676. {
  43677. return $this->releaseVersion;
  43678. }
  43679. public function extraVersion(): string
  43680. {
  43681. return $this->extraVersion;
  43682. }
  43683. public function versionId(): int
  43684. {
  43685. return $this->versionId;
  43686. }
  43687. /**
  43688. * @psalm-return list<string>
  43689. */
  43690. public function extensions(): array
  43691. {
  43692. return $this->extensions;
  43693. }
  43694. }
  43695. <?php
  43696. declare (strict_types=1);
  43697. /*
  43698. * This file is part of PHPUnit.
  43699. *
  43700. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43701. *
  43702. * For the full copyright and license information, please view the LICENSE
  43703. * file that was distributed with this source code.
  43704. */
  43705. namespace PHPUnit\Event\Runtime;
  43706. use PHPUnit\Runner\Version;
  43707. /**
  43708. * @psalm-immutable
  43709. *
  43710. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43711. */
  43712. final class PHPUnit
  43713. {
  43714. private readonly string $versionId;
  43715. private readonly string $releaseSeries;
  43716. public function __construct()
  43717. {
  43718. $this->versionId = Version::id();
  43719. $this->releaseSeries = Version::series();
  43720. }
  43721. public function versionId(): string
  43722. {
  43723. return $this->versionId;
  43724. }
  43725. public function releaseSeries(): string
  43726. {
  43727. return $this->releaseSeries;
  43728. }
  43729. }
  43730. <?php
  43731. declare (strict_types=1);
  43732. /*
  43733. * This file is part of PHPUnit.
  43734. *
  43735. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43736. *
  43737. * For the full copyright and license information, please view the LICENSE
  43738. * file that was distributed with this source code.
  43739. */
  43740. namespace PHPUnit\Event\Runtime;
  43741. use function sprintf;
  43742. /**
  43743. * @psalm-immutable
  43744. *
  43745. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43746. */
  43747. final class Runtime
  43748. {
  43749. private readonly \PHPUnit\Event\Runtime\OperatingSystem $operatingSystem;
  43750. private readonly \PHPUnit\Event\Runtime\PHP $php;
  43751. private readonly \PHPUnit\Event\Runtime\PHPUnit $phpunit;
  43752. public function __construct()
  43753. {
  43754. $this->operatingSystem = new \PHPUnit\Event\Runtime\OperatingSystem();
  43755. $this->php = new \PHPUnit\Event\Runtime\PHP();
  43756. $this->phpunit = new \PHPUnit\Event\Runtime\PHPUnit();
  43757. }
  43758. public function asString(): string
  43759. {
  43760. $php = $this->php();
  43761. return sprintf('PHPUnit %s using PHP %s (%s) on %s', $this->phpunit()->versionId(), $php->version(), $php->sapi(), $this->operatingSystem()->operatingSystem());
  43762. }
  43763. public function operatingSystem(): \PHPUnit\Event\Runtime\OperatingSystem
  43764. {
  43765. return $this->operatingSystem;
  43766. }
  43767. public function php(): \PHPUnit\Event\Runtime\PHP
  43768. {
  43769. return $this->php;
  43770. }
  43771. public function phpunit(): \PHPUnit\Event\Runtime\PHPUnit
  43772. {
  43773. return $this->phpunit;
  43774. }
  43775. }
  43776. <?php
  43777. declare (strict_types=1);
  43778. /*
  43779. * This file is part of PHPUnit.
  43780. *
  43781. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43782. *
  43783. * For the full copyright and license information, please view the LICENSE
  43784. * file that was distributed with this source code.
  43785. */
  43786. namespace PHPUnit\Event\Telemetry;
  43787. use function floor;
  43788. use function sprintf;
  43789. use PHPUnit\Event\InvalidArgumentException;
  43790. /**
  43791. * @psalm-immutable
  43792. *
  43793. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43794. */
  43795. final class Duration
  43796. {
  43797. private readonly int $seconds;
  43798. private readonly int $nanoseconds;
  43799. /**
  43800. * @throws InvalidArgumentException
  43801. */
  43802. public static function fromSecondsAndNanoseconds(int $seconds, int $nanoseconds): self
  43803. {
  43804. return new self($seconds, $nanoseconds);
  43805. }
  43806. /**
  43807. * @throws InvalidArgumentException
  43808. */
  43809. private function __construct(int $seconds, int $nanoseconds)
  43810. {
  43811. $this->ensureNotNegative($seconds, 'seconds');
  43812. $this->ensureNotNegative($nanoseconds, 'nanoseconds');
  43813. $this->ensureNanoSecondsInRange($nanoseconds);
  43814. $this->seconds = $seconds;
  43815. $this->nanoseconds = $nanoseconds;
  43816. }
  43817. public function seconds(): int
  43818. {
  43819. return $this->seconds;
  43820. }
  43821. public function nanoseconds(): int
  43822. {
  43823. return $this->nanoseconds;
  43824. }
  43825. public function asFloat(): float
  43826. {
  43827. return $this->seconds() + $this->nanoseconds() / 1000000000;
  43828. }
  43829. public function asString(): string
  43830. {
  43831. $seconds = $this->seconds();
  43832. $minutes = 0;
  43833. $hours = 0;
  43834. if ($seconds > 60 * 60) {
  43835. $hours = floor($seconds / 60 / 60);
  43836. $seconds -= $hours * 60 * 60;
  43837. }
  43838. if ($seconds > 60) {
  43839. $minutes = floor($seconds / 60);
  43840. $seconds -= $minutes * 60;
  43841. }
  43842. return sprintf('%02d:%02d:%02d.%09d', $hours, $minutes, $seconds, $this->nanoseconds());
  43843. }
  43844. public function equals(self $other): bool
  43845. {
  43846. return $this->seconds === $other->seconds && $this->nanoseconds === $other->nanoseconds;
  43847. }
  43848. public function isLessThan(self $other): bool
  43849. {
  43850. if ($this->seconds < $other->seconds) {
  43851. return \true;
  43852. }
  43853. if ($this->seconds > $other->seconds) {
  43854. return \false;
  43855. }
  43856. return $this->nanoseconds < $other->nanoseconds;
  43857. }
  43858. public function isGreaterThan(self $other): bool
  43859. {
  43860. if ($this->seconds > $other->seconds) {
  43861. return \true;
  43862. }
  43863. if ($this->seconds < $other->seconds) {
  43864. return \false;
  43865. }
  43866. return $this->nanoseconds > $other->nanoseconds;
  43867. }
  43868. /**
  43869. * @throws InvalidArgumentException
  43870. */
  43871. private function ensureNotNegative(int $value, string $type): void
  43872. {
  43873. if ($value < 0) {
  43874. throw new InvalidArgumentException(sprintf('Value for %s must not be negative.', $type));
  43875. }
  43876. }
  43877. /**
  43878. * @throws InvalidArgumentException
  43879. */
  43880. private function ensureNanoSecondsInRange(int $nanoseconds): void
  43881. {
  43882. if ($nanoseconds > 999999999) {
  43883. throw new InvalidArgumentException('Value for nanoseconds must not be greater than 999999999.');
  43884. }
  43885. }
  43886. }
  43887. <?php
  43888. declare (strict_types=1);
  43889. /*
  43890. * This file is part of PHPUnit.
  43891. *
  43892. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43893. *
  43894. * For the full copyright and license information, please view the LICENSE
  43895. * file that was distributed with this source code.
  43896. */
  43897. namespace PHPUnit\Event\Telemetry;
  43898. use PHPUnit\Event\RuntimeException;
  43899. /**
  43900. * @psalm-immutable
  43901. *
  43902. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  43903. */
  43904. final class GarbageCollectorStatus
  43905. {
  43906. private readonly int $runs;
  43907. private readonly int $collected;
  43908. private readonly int $threshold;
  43909. private readonly int $roots;
  43910. private readonly ?float $applicationTime;
  43911. private readonly ?float $collectorTime;
  43912. private readonly ?float $destructorTime;
  43913. private readonly ?float $freeTime;
  43914. private readonly ?bool $running;
  43915. private readonly ?bool $protected;
  43916. private readonly ?bool $full;
  43917. private readonly ?int $bufferSize;
  43918. public function __construct(int $runs, int $collected, int $threshold, int $roots, ?float $applicationTime, ?float $collectorTime, ?float $destructorTime, ?float $freeTime, ?bool $running, ?bool $protected, ?bool $full, ?int $bufferSize)
  43919. {
  43920. $this->runs = $runs;
  43921. $this->collected = $collected;
  43922. $this->threshold = $threshold;
  43923. $this->roots = $roots;
  43924. $this->applicationTime = $applicationTime;
  43925. $this->collectorTime = $collectorTime;
  43926. $this->destructorTime = $destructorTime;
  43927. $this->freeTime = $freeTime;
  43928. $this->running = $running;
  43929. $this->protected = $protected;
  43930. $this->full = $full;
  43931. $this->bufferSize = $bufferSize;
  43932. }
  43933. public function runs(): int
  43934. {
  43935. return $this->runs;
  43936. }
  43937. public function collected(): int
  43938. {
  43939. return $this->collected;
  43940. }
  43941. public function threshold(): int
  43942. {
  43943. return $this->threshold;
  43944. }
  43945. public function roots(): int
  43946. {
  43947. return $this->roots;
  43948. }
  43949. /**
  43950. * @psalm-assert-if-true !null $this->applicationTime
  43951. * @psalm-assert-if-true !null $this->collectorTime
  43952. * @psalm-assert-if-true !null $this->destructorTime
  43953. * @psalm-assert-if-true !null $this->freeTime
  43954. * @psalm-assert-if-true !null $this->running
  43955. * @psalm-assert-if-true !null $this->protected
  43956. * @psalm-assert-if-true !null $this->full
  43957. * @psalm-assert-if-true !null $this->bufferSize
  43958. */
  43959. public function hasExtendedInformation(): bool
  43960. {
  43961. return $this->running !== null;
  43962. }
  43963. /**
  43964. * @throws RuntimeException on PHP < 8.3
  43965. */
  43966. public function applicationTime(): float
  43967. {
  43968. if ($this->applicationTime === null) {
  43969. throw new RuntimeException('Information not available');
  43970. }
  43971. return $this->applicationTime;
  43972. }
  43973. /**
  43974. * @throws RuntimeException on PHP < 8.3
  43975. */
  43976. public function collectorTime(): float
  43977. {
  43978. if ($this->collectorTime === null) {
  43979. throw new RuntimeException('Information not available');
  43980. }
  43981. return $this->collectorTime;
  43982. }
  43983. /**
  43984. * @throws RuntimeException on PHP < 8.3
  43985. */
  43986. public function destructorTime(): float
  43987. {
  43988. if ($this->destructorTime === null) {
  43989. throw new RuntimeException('Information not available');
  43990. }
  43991. return $this->destructorTime;
  43992. }
  43993. /**
  43994. * @throws RuntimeException on PHP < 8.3
  43995. */
  43996. public function freeTime(): float
  43997. {
  43998. if ($this->freeTime === null) {
  43999. throw new RuntimeException('Information not available');
  44000. }
  44001. return $this->freeTime;
  44002. }
  44003. /**
  44004. * @throws RuntimeException on PHP < 8.3
  44005. */
  44006. public function isRunning(): bool
  44007. {
  44008. if ($this->running === null) {
  44009. throw new RuntimeException('Information not available');
  44010. }
  44011. return $this->running;
  44012. }
  44013. /**
  44014. * @throws RuntimeException on PHP < 8.3
  44015. */
  44016. public function isProtected(): bool
  44017. {
  44018. if ($this->protected === null) {
  44019. throw new RuntimeException('Information not available');
  44020. }
  44021. return $this->protected;
  44022. }
  44023. /**
  44024. * @throws RuntimeException on PHP < 8.3
  44025. */
  44026. public function isFull(): bool
  44027. {
  44028. if ($this->full === null) {
  44029. throw new RuntimeException('Information not available');
  44030. }
  44031. return $this->full;
  44032. }
  44033. /**
  44034. * @throws RuntimeException on PHP < 8.3
  44035. */
  44036. public function bufferSize(): int
  44037. {
  44038. if ($this->bufferSize === null) {
  44039. throw new RuntimeException('Information not available');
  44040. }
  44041. return $this->bufferSize;
  44042. }
  44043. }
  44044. <?php
  44045. declare (strict_types=1);
  44046. /*
  44047. * This file is part of PHPUnit.
  44048. *
  44049. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44050. *
  44051. * For the full copyright and license information, please view the LICENSE
  44052. * file that was distributed with this source code.
  44053. */
  44054. namespace PHPUnit\Event\Telemetry;
  44055. /**
  44056. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44057. *
  44058. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  44059. */
  44060. interface GarbageCollectorStatusProvider
  44061. {
  44062. public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus;
  44063. }
  44064. <?php
  44065. declare (strict_types=1);
  44066. /*
  44067. * This file is part of PHPUnit.
  44068. *
  44069. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44070. *
  44071. * For the full copyright and license information, please view the LICENSE
  44072. * file that was distributed with this source code.
  44073. */
  44074. namespace PHPUnit\Event\Telemetry;
  44075. use function sprintf;
  44076. use PHPUnit\Event\InvalidArgumentException;
  44077. /**
  44078. * @psalm-immutable
  44079. *
  44080. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44081. */
  44082. final class HRTime
  44083. {
  44084. private readonly int $seconds;
  44085. private readonly int $nanoseconds;
  44086. /**
  44087. * @throws InvalidArgumentException
  44088. */
  44089. public static function fromSecondsAndNanoseconds(int $seconds, int $nanoseconds): self
  44090. {
  44091. return new self($seconds, $nanoseconds);
  44092. }
  44093. /**
  44094. * @throws InvalidArgumentException
  44095. */
  44096. private function __construct(int $seconds, int $nanoseconds)
  44097. {
  44098. $this->ensureNotNegative($seconds, 'seconds');
  44099. $this->ensureNotNegative($nanoseconds, 'nanoseconds');
  44100. $this->ensureNanoSecondsInRange($nanoseconds);
  44101. $this->seconds = $seconds;
  44102. $this->nanoseconds = $nanoseconds;
  44103. }
  44104. public function seconds(): int
  44105. {
  44106. return $this->seconds;
  44107. }
  44108. public function nanoseconds(): int
  44109. {
  44110. return $this->nanoseconds;
  44111. }
  44112. public function duration(self $start): \PHPUnit\Event\Telemetry\Duration
  44113. {
  44114. $seconds = $this->seconds - $start->seconds();
  44115. $nanoseconds = $this->nanoseconds - $start->nanoseconds();
  44116. if ($nanoseconds < 0) {
  44117. $seconds--;
  44118. $nanoseconds += 1000000000;
  44119. }
  44120. if ($seconds < 0) {
  44121. return \PHPUnit\Event\Telemetry\Duration::fromSecondsAndNanoseconds(0, 0);
  44122. }
  44123. return \PHPUnit\Event\Telemetry\Duration::fromSecondsAndNanoseconds($seconds, $nanoseconds);
  44124. }
  44125. /**
  44126. * @throws InvalidArgumentException
  44127. */
  44128. private function ensureNotNegative(int $value, string $type): void
  44129. {
  44130. if ($value < 0) {
  44131. throw new InvalidArgumentException(sprintf('Value for %s must not be negative.', $type));
  44132. }
  44133. }
  44134. /**
  44135. * @throws InvalidArgumentException
  44136. */
  44137. private function ensureNanoSecondsInRange(int $nanoseconds): void
  44138. {
  44139. if ($nanoseconds > 999999999) {
  44140. throw new InvalidArgumentException('Value for nanoseconds must not be greater than 999999999.');
  44141. }
  44142. }
  44143. }
  44144. <?php
  44145. declare (strict_types=1);
  44146. /*
  44147. * This file is part of PHPUnit.
  44148. *
  44149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44150. *
  44151. * For the full copyright and license information, please view the LICENSE
  44152. * file that was distributed with this source code.
  44153. */
  44154. namespace PHPUnit\Event\Telemetry;
  44155. use function sprintf;
  44156. /**
  44157. * @psalm-immutable
  44158. *
  44159. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44160. */
  44161. final class Info
  44162. {
  44163. private readonly \PHPUnit\Event\Telemetry\Snapshot $current;
  44164. private readonly \PHPUnit\Event\Telemetry\Duration $durationSinceStart;
  44165. private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memorySinceStart;
  44166. private readonly \PHPUnit\Event\Telemetry\Duration $durationSincePrevious;
  44167. private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memorySincePrevious;
  44168. public function __construct(\PHPUnit\Event\Telemetry\Snapshot $current, \PHPUnit\Event\Telemetry\Duration $durationSinceStart, \PHPUnit\Event\Telemetry\MemoryUsage $memorySinceStart, \PHPUnit\Event\Telemetry\Duration $durationSincePrevious, \PHPUnit\Event\Telemetry\MemoryUsage $memorySincePrevious)
  44169. {
  44170. $this->current = $current;
  44171. $this->durationSinceStart = $durationSinceStart;
  44172. $this->memorySinceStart = $memorySinceStart;
  44173. $this->durationSincePrevious = $durationSincePrevious;
  44174. $this->memorySincePrevious = $memorySincePrevious;
  44175. }
  44176. public function time(): \PHPUnit\Event\Telemetry\HRTime
  44177. {
  44178. return $this->current->time();
  44179. }
  44180. public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44181. {
  44182. return $this->current->memoryUsage();
  44183. }
  44184. public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44185. {
  44186. return $this->current->peakMemoryUsage();
  44187. }
  44188. public function durationSinceStart(): \PHPUnit\Event\Telemetry\Duration
  44189. {
  44190. return $this->durationSinceStart;
  44191. }
  44192. public function memoryUsageSinceStart(): \PHPUnit\Event\Telemetry\MemoryUsage
  44193. {
  44194. return $this->memorySinceStart;
  44195. }
  44196. public function durationSincePrevious(): \PHPUnit\Event\Telemetry\Duration
  44197. {
  44198. return $this->durationSincePrevious;
  44199. }
  44200. public function memoryUsageSincePrevious(): \PHPUnit\Event\Telemetry\MemoryUsage
  44201. {
  44202. return $this->memorySincePrevious;
  44203. }
  44204. public function garbageCollectorStatus(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
  44205. {
  44206. return $this->current->garbageCollectorStatus();
  44207. }
  44208. public function asString(): string
  44209. {
  44210. return sprintf('[%s / %s] [%d bytes]', $this->durationSinceStart()->asString(), $this->durationSincePrevious()->asString(), $this->memoryUsage()->bytes());
  44211. }
  44212. }
  44213. <?php
  44214. declare (strict_types=1);
  44215. /*
  44216. * This file is part of PHPUnit.
  44217. *
  44218. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44219. *
  44220. * For the full copyright and license information, please view the LICENSE
  44221. * file that was distributed with this source code.
  44222. */
  44223. namespace PHPUnit\Event\Telemetry;
  44224. /**
  44225. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44226. *
  44227. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  44228. */
  44229. interface MemoryMeter
  44230. {
  44231. public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage;
  44232. public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage;
  44233. }
  44234. <?php
  44235. declare (strict_types=1);
  44236. /*
  44237. * This file is part of PHPUnit.
  44238. *
  44239. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44240. *
  44241. * For the full copyright and license information, please view the LICENSE
  44242. * file that was distributed with this source code.
  44243. */
  44244. namespace PHPUnit\Event\Telemetry;
  44245. /**
  44246. * @psalm-immutable
  44247. *
  44248. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44249. */
  44250. final class MemoryUsage
  44251. {
  44252. private readonly int $bytes;
  44253. public static function fromBytes(int $bytes): self
  44254. {
  44255. return new self($bytes);
  44256. }
  44257. private function __construct(int $bytes)
  44258. {
  44259. $this->bytes = $bytes;
  44260. }
  44261. public function bytes(): int
  44262. {
  44263. return $this->bytes;
  44264. }
  44265. public function diff(self $other): self
  44266. {
  44267. return self::fromBytes($this->bytes - $other->bytes);
  44268. }
  44269. }
  44270. <?php
  44271. declare (strict_types=1);
  44272. /*
  44273. * This file is part of PHPUnit.
  44274. *
  44275. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44276. *
  44277. * For the full copyright and license information, please view the LICENSE
  44278. * file that was distributed with this source code.
  44279. */
  44280. namespace PHPUnit\Event\Telemetry;
  44281. use function gc_status;
  44282. /**
  44283. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44284. *
  44285. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44286. *
  44287. * @codeCoverageIgnore
  44288. */
  44289. final class Php81GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
  44290. {
  44291. public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
  44292. {
  44293. $status = gc_status();
  44294. return new \PHPUnit\Event\Telemetry\GarbageCollectorStatus($status['runs'], $status['collected'], $status['threshold'], $status['roots'], null, null, null, null, null, null, null, null);
  44295. }
  44296. }
  44297. <?php
  44298. declare (strict_types=1);
  44299. /*
  44300. * This file is part of PHPUnit.
  44301. *
  44302. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44303. *
  44304. * For the full copyright and license information, please view the LICENSE
  44305. * file that was distributed with this source code.
  44306. */
  44307. namespace PHPUnit\Event\Telemetry;
  44308. use function gc_status;
  44309. /**
  44310. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44311. *
  44312. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44313. */
  44314. final class Php83GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
  44315. {
  44316. public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
  44317. {
  44318. $status = gc_status();
  44319. return new \PHPUnit\Event\Telemetry\GarbageCollectorStatus($status['runs'], $status['collected'], $status['threshold'], $status['roots'], $status['application_time'], $status['collector_time'], $status['destructor_time'], $status['free_time'], $status['running'], $status['protected'], $status['full'], $status['buffer_size']);
  44320. }
  44321. }
  44322. <?php
  44323. declare (strict_types=1);
  44324. /*
  44325. * This file is part of PHPUnit.
  44326. *
  44327. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44328. *
  44329. * For the full copyright and license information, please view the LICENSE
  44330. * file that was distributed with this source code.
  44331. */
  44332. namespace PHPUnit\Event\Telemetry;
  44333. /**
  44334. * @psalm-immutable
  44335. *
  44336. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44337. */
  44338. final class Snapshot
  44339. {
  44340. private readonly \PHPUnit\Event\Telemetry\HRTime $time;
  44341. private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage;
  44342. private readonly \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage;
  44343. private readonly \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus;
  44344. public function __construct(\PHPUnit\Event\Telemetry\HRTime $time, \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage, \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage, \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus)
  44345. {
  44346. $this->time = $time;
  44347. $this->memoryUsage = $memoryUsage;
  44348. $this->peakMemoryUsage = $peakMemoryUsage;
  44349. $this->garbageCollectorStatus = $garbageCollectorStatus;
  44350. }
  44351. public function time(): \PHPUnit\Event\Telemetry\HRTime
  44352. {
  44353. return $this->time;
  44354. }
  44355. public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44356. {
  44357. return $this->memoryUsage;
  44358. }
  44359. public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44360. {
  44361. return $this->peakMemoryUsage;
  44362. }
  44363. public function garbageCollectorStatus(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
  44364. {
  44365. return $this->garbageCollectorStatus;
  44366. }
  44367. }
  44368. <?php
  44369. declare (strict_types=1);
  44370. /*
  44371. * This file is part of PHPUnit.
  44372. *
  44373. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44374. *
  44375. * For the full copyright and license information, please view the LICENSE
  44376. * file that was distributed with this source code.
  44377. */
  44378. namespace PHPUnit\Event\Telemetry;
  44379. /**
  44380. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44381. *
  44382. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  44383. */
  44384. interface StopWatch
  44385. {
  44386. public function current(): \PHPUnit\Event\Telemetry\HRTime;
  44387. }
  44388. <?php
  44389. declare (strict_types=1);
  44390. /*
  44391. * This file is part of PHPUnit.
  44392. *
  44393. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44394. *
  44395. * For the full copyright and license information, please view the LICENSE
  44396. * file that was distributed with this source code.
  44397. */
  44398. namespace PHPUnit\Event\Telemetry;
  44399. /**
  44400. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44401. *
  44402. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44403. */
  44404. final class System
  44405. {
  44406. private readonly \PHPUnit\Event\Telemetry\StopWatch $stopWatch;
  44407. private readonly \PHPUnit\Event\Telemetry\MemoryMeter $memoryMeter;
  44408. private readonly \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider $garbageCollectorStatusProvider;
  44409. public function __construct(\PHPUnit\Event\Telemetry\StopWatch $stopWatch, \PHPUnit\Event\Telemetry\MemoryMeter $memoryMeter, \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider $garbageCollectorStatusProvider)
  44410. {
  44411. $this->stopWatch = $stopWatch;
  44412. $this->memoryMeter = $memoryMeter;
  44413. $this->garbageCollectorStatusProvider = $garbageCollectorStatusProvider;
  44414. }
  44415. public function snapshot(): \PHPUnit\Event\Telemetry\Snapshot
  44416. {
  44417. return new \PHPUnit\Event\Telemetry\Snapshot($this->stopWatch->current(), $this->memoryMeter->memoryUsage(), $this->memoryMeter->peakMemoryUsage(), $this->garbageCollectorStatusProvider->status());
  44418. }
  44419. }
  44420. <?php
  44421. declare (strict_types=1);
  44422. /*
  44423. * This file is part of PHPUnit.
  44424. *
  44425. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44426. *
  44427. * For the full copyright and license information, please view the LICENSE
  44428. * file that was distributed with this source code.
  44429. */
  44430. namespace PHPUnit\Event\Telemetry;
  44431. use function memory_get_peak_usage;
  44432. use function memory_get_usage;
  44433. /**
  44434. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44435. *
  44436. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44437. */
  44438. final class SystemMemoryMeter implements \PHPUnit\Event\Telemetry\MemoryMeter
  44439. {
  44440. public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44441. {
  44442. return \PHPUnit\Event\Telemetry\MemoryUsage::fromBytes(memory_get_usage(\true));
  44443. }
  44444. public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
  44445. {
  44446. return \PHPUnit\Event\Telemetry\MemoryUsage::fromBytes(memory_get_peak_usage(\true));
  44447. }
  44448. }
  44449. <?php
  44450. declare (strict_types=1);
  44451. /*
  44452. * This file is part of PHPUnit.
  44453. *
  44454. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44455. *
  44456. * For the full copyright and license information, please view the LICENSE
  44457. * file that was distributed with this source code.
  44458. */
  44459. namespace PHPUnit\Event\Telemetry;
  44460. use function hrtime;
  44461. use PHPUnit\Event\InvalidArgumentException;
  44462. /**
  44463. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44464. *
  44465. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44466. */
  44467. final class SystemStopWatch implements \PHPUnit\Event\Telemetry\StopWatch
  44468. {
  44469. /**
  44470. * @throws InvalidArgumentException
  44471. */
  44472. public function current(): \PHPUnit\Event\Telemetry\HRTime
  44473. {
  44474. return \PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(...hrtime());
  44475. }
  44476. }
  44477. <?php
  44478. declare (strict_types=1);
  44479. /*
  44480. * This file is part of PHPUnit.
  44481. *
  44482. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44483. *
  44484. * For the full copyright and license information, please view the LICENSE
  44485. * file that was distributed with this source code.
  44486. */
  44487. namespace PHPUnit\Event\Telemetry;
  44488. use function hrtime;
  44489. use PHPUnit\Event\InvalidArgumentException;
  44490. /**
  44491. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44492. *
  44493. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  44494. *
  44495. * @codeCoverageIgnore
  44496. */
  44497. final class SystemStopWatchWithOffset implements \PHPUnit\Event\Telemetry\StopWatch
  44498. {
  44499. private ?\PHPUnit\Event\Telemetry\HRTime $offset;
  44500. public function __construct(\PHPUnit\Event\Telemetry\HRTime $offset)
  44501. {
  44502. $this->offset = $offset;
  44503. }
  44504. /**
  44505. * @throws InvalidArgumentException
  44506. */
  44507. public function current(): \PHPUnit\Event\Telemetry\HRTime
  44508. {
  44509. if ($this->offset !== null) {
  44510. $offset = $this->offset;
  44511. $this->offset = null;
  44512. return $offset;
  44513. }
  44514. return \PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(...hrtime());
  44515. }
  44516. }
  44517. <?php
  44518. declare (strict_types=1);
  44519. /*
  44520. * This file is part of PHPUnit.
  44521. *
  44522. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44523. *
  44524. * For the full copyright and license information, please view the LICENSE
  44525. * file that was distributed with this source code.
  44526. */
  44527. namespace PHPUnit\Event\Code;
  44528. /**
  44529. * @psalm-immutable
  44530. *
  44531. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44532. */
  44533. final class Phpt extends \PHPUnit\Event\Code\Test
  44534. {
  44535. /**
  44536. * @psalm-assert-if-true Phpt $this
  44537. */
  44538. public function isPhpt(): bool
  44539. {
  44540. return \true;
  44541. }
  44542. /**
  44543. * @psalm-return non-empty-string
  44544. */
  44545. public function id(): string
  44546. {
  44547. return $this->file();
  44548. }
  44549. /**
  44550. * @psalm-return non-empty-string
  44551. */
  44552. public function name(): string
  44553. {
  44554. return $this->file();
  44555. }
  44556. }
  44557. <?php
  44558. declare (strict_types=1);
  44559. /*
  44560. * This file is part of PHPUnit.
  44561. *
  44562. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44563. *
  44564. * For the full copyright and license information, please view the LICENSE
  44565. * file that was distributed with this source code.
  44566. */
  44567. namespace PHPUnit\Event\Code;
  44568. /**
  44569. * @psalm-immutable
  44570. *
  44571. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44572. */
  44573. abstract class Test
  44574. {
  44575. /**
  44576. * @psalm-var non-empty-string
  44577. */
  44578. private readonly string $file;
  44579. /**
  44580. * @psalm-param non-empty-string $file
  44581. */
  44582. public function __construct(string $file)
  44583. {
  44584. $this->file = $file;
  44585. }
  44586. /**
  44587. * @psalm-return non-empty-string
  44588. */
  44589. public function file(): string
  44590. {
  44591. return $this->file;
  44592. }
  44593. /**
  44594. * @psalm-assert-if-true TestMethod $this
  44595. */
  44596. public function isTestMethod(): bool
  44597. {
  44598. return \false;
  44599. }
  44600. /**
  44601. * @psalm-assert-if-true Phpt $this
  44602. */
  44603. public function isPhpt(): bool
  44604. {
  44605. return \false;
  44606. }
  44607. /**
  44608. * @psalm-return non-empty-string
  44609. */
  44610. abstract public function id(): string;
  44611. /**
  44612. * @psalm-return non-empty-string
  44613. */
  44614. abstract public function name(): string;
  44615. }
  44616. <?php
  44617. declare (strict_types=1);
  44618. /*
  44619. * This file is part of PHPUnit.
  44620. *
  44621. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44622. *
  44623. * For the full copyright and license information, please view the LICENSE
  44624. * file that was distributed with this source code.
  44625. */
  44626. namespace PHPUnit\Event\Code;
  44627. use function count;
  44628. use Countable;
  44629. use IteratorAggregate;
  44630. /**
  44631. * @template-implements IteratorAggregate<int, Test>
  44632. *
  44633. * @psalm-immutable
  44634. *
  44635. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44636. */
  44637. final class TestCollection implements Countable, IteratorAggregate
  44638. {
  44639. /**
  44640. * @psalm-var list<Test>
  44641. */
  44642. private readonly array $tests;
  44643. /**
  44644. * @psalm-param list<Test> $tests
  44645. */
  44646. public static function fromArray(array $tests): self
  44647. {
  44648. return new self(...$tests);
  44649. }
  44650. private function __construct(\PHPUnit\Event\Code\Test ...$tests)
  44651. {
  44652. $this->tests = $tests;
  44653. }
  44654. /**
  44655. * @psalm-return list<Test>
  44656. */
  44657. public function asArray(): array
  44658. {
  44659. return $this->tests;
  44660. }
  44661. public function count(): int
  44662. {
  44663. return count($this->tests);
  44664. }
  44665. public function getIterator(): \PHPUnit\Event\Code\TestCollectionIterator
  44666. {
  44667. return new \PHPUnit\Event\Code\TestCollectionIterator($this);
  44668. }
  44669. }
  44670. <?php
  44671. declare (strict_types=1);
  44672. /*
  44673. * This file is part of PHPUnit.
  44674. *
  44675. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44676. *
  44677. * For the full copyright and license information, please view the LICENSE
  44678. * file that was distributed with this source code.
  44679. */
  44680. namespace PHPUnit\Event\Code;
  44681. use function count;
  44682. use Iterator;
  44683. /**
  44684. * @template-implements Iterator<int, Test>
  44685. *
  44686. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44687. */
  44688. final class TestCollectionIterator implements Iterator
  44689. {
  44690. /**
  44691. * @psalm-var list<Test>
  44692. */
  44693. private readonly array $tests;
  44694. private int $position = 0;
  44695. public function __construct(\PHPUnit\Event\Code\TestCollection $tests)
  44696. {
  44697. $this->tests = $tests->asArray();
  44698. }
  44699. public function rewind(): void
  44700. {
  44701. $this->position = 0;
  44702. }
  44703. public function valid(): bool
  44704. {
  44705. return $this->position < count($this->tests);
  44706. }
  44707. public function key(): int
  44708. {
  44709. return $this->position;
  44710. }
  44711. public function current(): \PHPUnit\Event\Code\Test
  44712. {
  44713. return $this->tests[$this->position];
  44714. }
  44715. public function next(): void
  44716. {
  44717. $this->position++;
  44718. }
  44719. }
  44720. <?php
  44721. declare (strict_types=1);
  44722. /*
  44723. * This file is part of PHPUnit.
  44724. *
  44725. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44726. *
  44727. * For the full copyright and license information, please view the LICENSE
  44728. * file that was distributed with this source code.
  44729. */
  44730. namespace PHPUnit\Event\TestData;
  44731. /**
  44732. * @psalm-immutable
  44733. *
  44734. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44735. */
  44736. final class DataFromDataProvider extends \PHPUnit\Event\TestData\TestData
  44737. {
  44738. private readonly int|string $dataSetName;
  44739. private readonly string $dataAsStringForResultOutput;
  44740. public static function from(int|string $dataSetName, string $data, string $dataAsStringForResultOutput): self
  44741. {
  44742. return new self($dataSetName, $data, $dataAsStringForResultOutput);
  44743. }
  44744. protected function __construct(int|string $dataSetName, string $data, string $dataAsStringForResultOutput)
  44745. {
  44746. $this->dataSetName = $dataSetName;
  44747. $this->dataAsStringForResultOutput = $dataAsStringForResultOutput;
  44748. parent::__construct($data);
  44749. }
  44750. public function dataSetName(): int|string
  44751. {
  44752. return $this->dataSetName;
  44753. }
  44754. /**
  44755. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  44756. */
  44757. public function dataAsStringForResultOutput(): string
  44758. {
  44759. return $this->dataAsStringForResultOutput;
  44760. }
  44761. /**
  44762. * @psalm-assert-if-true DataFromDataProvider $this
  44763. */
  44764. public function isFromDataProvider(): bool
  44765. {
  44766. return \true;
  44767. }
  44768. }
  44769. <?php
  44770. declare (strict_types=1);
  44771. /*
  44772. * This file is part of PHPUnit.
  44773. *
  44774. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44775. *
  44776. * For the full copyright and license information, please view the LICENSE
  44777. * file that was distributed with this source code.
  44778. */
  44779. namespace PHPUnit\Event\TestData;
  44780. /**
  44781. * @psalm-immutable
  44782. *
  44783. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44784. */
  44785. final class DataFromTestDependency extends \PHPUnit\Event\TestData\TestData
  44786. {
  44787. public static function from(string $data): self
  44788. {
  44789. return new self($data);
  44790. }
  44791. /**
  44792. * @psalm-assert-if-true DataFromTestDependency $this
  44793. */
  44794. public function isFromTestDependency(): bool
  44795. {
  44796. return \true;
  44797. }
  44798. }
  44799. <?php
  44800. declare (strict_types=1);
  44801. /*
  44802. * This file is part of PHPUnit.
  44803. *
  44804. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44805. *
  44806. * For the full copyright and license information, please view the LICENSE
  44807. * file that was distributed with this source code.
  44808. */
  44809. namespace PHPUnit\Event\TestData;
  44810. /**
  44811. * @psalm-immutable
  44812. *
  44813. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44814. */
  44815. abstract class TestData
  44816. {
  44817. private readonly string $data;
  44818. protected function __construct(string $data)
  44819. {
  44820. $this->data = $data;
  44821. }
  44822. public function data(): string
  44823. {
  44824. return $this->data;
  44825. }
  44826. /**
  44827. * @psalm-assert-if-true DataFromDataProvider $this
  44828. */
  44829. public function isFromDataProvider(): bool
  44830. {
  44831. return \false;
  44832. }
  44833. /**
  44834. * @psalm-assert-if-true DataFromTestDependency $this
  44835. */
  44836. public function isFromTestDependency(): bool
  44837. {
  44838. return \false;
  44839. }
  44840. }
  44841. <?php
  44842. declare (strict_types=1);
  44843. /*
  44844. * This file is part of PHPUnit.
  44845. *
  44846. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44847. *
  44848. * For the full copyright and license information, please view the LICENSE
  44849. * file that was distributed with this source code.
  44850. */
  44851. namespace PHPUnit\Event\TestData;
  44852. use function count;
  44853. use Countable;
  44854. use IteratorAggregate;
  44855. /**
  44856. * @template-implements IteratorAggregate<int, TestData>
  44857. *
  44858. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44859. */
  44860. final class TestDataCollection implements Countable, IteratorAggregate
  44861. {
  44862. /**
  44863. * @psalm-var list<TestData>
  44864. */
  44865. private readonly array $data;
  44866. private ?\PHPUnit\Event\TestData\DataFromDataProvider $fromDataProvider = null;
  44867. /**
  44868. * @psalm-param list<TestData> $data
  44869. *
  44870. * @throws MoreThanOneDataSetFromDataProviderException
  44871. */
  44872. public static function fromArray(array $data): self
  44873. {
  44874. return new self(...$data);
  44875. }
  44876. /**
  44877. * @throws MoreThanOneDataSetFromDataProviderException
  44878. */
  44879. private function __construct(\PHPUnit\Event\TestData\TestData ...$data)
  44880. {
  44881. $this->ensureNoMoreThanOneDataFromDataProvider($data);
  44882. $this->data = $data;
  44883. }
  44884. /**
  44885. * @psalm-return list<TestData>
  44886. */
  44887. public function asArray(): array
  44888. {
  44889. return $this->data;
  44890. }
  44891. public function count(): int
  44892. {
  44893. return count($this->data);
  44894. }
  44895. /**
  44896. * @psalm-assert-if-true !null $this->fromDataProvider
  44897. */
  44898. public function hasDataFromDataProvider(): bool
  44899. {
  44900. return $this->fromDataProvider !== null;
  44901. }
  44902. /**
  44903. * @throws NoDataSetFromDataProviderException
  44904. */
  44905. public function dataFromDataProvider(): \PHPUnit\Event\TestData\DataFromDataProvider
  44906. {
  44907. if (!$this->hasDataFromDataProvider()) {
  44908. throw new \PHPUnit\Event\TestData\NoDataSetFromDataProviderException();
  44909. }
  44910. return $this->fromDataProvider;
  44911. }
  44912. public function getIterator(): \PHPUnit\Event\TestData\TestDataCollectionIterator
  44913. {
  44914. return new \PHPUnit\Event\TestData\TestDataCollectionIterator($this);
  44915. }
  44916. /**
  44917. * @psalm-param list<TestData> $data
  44918. *
  44919. * @throws MoreThanOneDataSetFromDataProviderException
  44920. */
  44921. private function ensureNoMoreThanOneDataFromDataProvider(array $data): void
  44922. {
  44923. foreach ($data as $_data) {
  44924. if ($_data->isFromDataProvider()) {
  44925. if ($this->fromDataProvider !== null) {
  44926. throw new \PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException();
  44927. }
  44928. $this->fromDataProvider = $_data;
  44929. }
  44930. }
  44931. }
  44932. }
  44933. <?php
  44934. declare (strict_types=1);
  44935. /*
  44936. * This file is part of PHPUnit.
  44937. *
  44938. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44939. *
  44940. * For the full copyright and license information, please view the LICENSE
  44941. * file that was distributed with this source code.
  44942. */
  44943. namespace PHPUnit\Event\TestData;
  44944. use function count;
  44945. use Iterator;
  44946. /**
  44947. * @template-implements Iterator<int, TestData>
  44948. *
  44949. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44950. */
  44951. final class TestDataCollectionIterator implements Iterator
  44952. {
  44953. /**
  44954. * @psalm-var list<TestData>
  44955. */
  44956. private readonly array $data;
  44957. private int $position = 0;
  44958. public function __construct(\PHPUnit\Event\TestData\TestDataCollection $data)
  44959. {
  44960. $this->data = $data->asArray();
  44961. }
  44962. public function rewind(): void
  44963. {
  44964. $this->position = 0;
  44965. }
  44966. public function valid(): bool
  44967. {
  44968. return $this->position < count($this->data);
  44969. }
  44970. public function key(): int
  44971. {
  44972. return $this->position;
  44973. }
  44974. public function current(): \PHPUnit\Event\TestData\TestData
  44975. {
  44976. return $this->data[$this->position];
  44977. }
  44978. public function next(): void
  44979. {
  44980. $this->position++;
  44981. }
  44982. }
  44983. <?php
  44984. declare (strict_types=1);
  44985. /*
  44986. * This file is part of PHPUnit.
  44987. *
  44988. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44989. *
  44990. * For the full copyright and license information, please view the LICENSE
  44991. * file that was distributed with this source code.
  44992. */
  44993. namespace PHPUnit\Event\Code;
  44994. /**
  44995. * @psalm-immutable
  44996. *
  44997. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  44998. */
  44999. final class TestDox
  45000. {
  45001. private readonly string $prettifiedClassName;
  45002. private readonly string $prettifiedMethodName;
  45003. private readonly string $prettifiedAndColorizedMethodName;
  45004. public function __construct(string $prettifiedClassName, string $prettifiedMethodName, string $prettifiedAndColorizedMethodName)
  45005. {
  45006. $this->prettifiedClassName = $prettifiedClassName;
  45007. $this->prettifiedMethodName = $prettifiedMethodName;
  45008. $this->prettifiedAndColorizedMethodName = $prettifiedAndColorizedMethodName;
  45009. }
  45010. public function prettifiedClassName(): string
  45011. {
  45012. return $this->prettifiedClassName;
  45013. }
  45014. public function prettifiedMethodName(bool $colorize = \false): string
  45015. {
  45016. if ($colorize) {
  45017. return $this->prettifiedAndColorizedMethodName;
  45018. }
  45019. return $this->prettifiedMethodName;
  45020. }
  45021. }
  45022. <?php
  45023. declare (strict_types=1);
  45024. /*
  45025. * This file is part of PHPUnit.
  45026. *
  45027. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45028. *
  45029. * For the full copyright and license information, please view the LICENSE
  45030. * file that was distributed with this source code.
  45031. */
  45032. namespace PHPUnit\Event\Code;
  45033. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  45034. use PHPUnit\Framework\TestCase;
  45035. use PHPUnit\Logging\TestDox\NamePrettifier;
  45036. /**
  45037. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45038. *
  45039. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  45040. */
  45041. final class TestDoxBuilder
  45042. {
  45043. /**
  45044. * @throws MoreThanOneDataSetFromDataProviderException
  45045. */
  45046. public static function fromTestCase(TestCase $testCase): \PHPUnit\Event\Code\TestDox
  45047. {
  45048. $prettifier = new NamePrettifier();
  45049. return new \PHPUnit\Event\Code\TestDox($prettifier->prettifyTestClassName($testCase::class), $prettifier->prettifyTestCase($testCase, \false), $prettifier->prettifyTestCase($testCase, \true));
  45050. }
  45051. /**
  45052. * @psalm-param class-string $className
  45053. * @psalm-param non-empty-string $methodName
  45054. */
  45055. public static function fromClassNameAndMethodName(string $className, string $methodName): \PHPUnit\Event\Code\TestDox
  45056. {
  45057. $prettifier = new NamePrettifier();
  45058. $prettifiedMethodName = $prettifier->prettifyTestMethodName($methodName);
  45059. return new \PHPUnit\Event\Code\TestDox($prettifier->prettifyTestClassName($className), $prettifiedMethodName, $prettifiedMethodName);
  45060. }
  45061. }
  45062. <?php
  45063. declare (strict_types=1);
  45064. /*
  45065. * This file is part of PHPUnit.
  45066. *
  45067. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45068. *
  45069. * For the full copyright and license information, please view the LICENSE
  45070. * file that was distributed with this source code.
  45071. */
  45072. namespace PHPUnit\Event\Code;
  45073. use function assert;
  45074. use function is_int;
  45075. use function sprintf;
  45076. use PHPUnit\Event\TestData\TestDataCollection;
  45077. use PHPUnit\Metadata\MetadataCollection;
  45078. /**
  45079. * @psalm-immutable
  45080. *
  45081. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45082. */
  45083. final class TestMethod extends \PHPUnit\Event\Code\Test
  45084. {
  45085. /**
  45086. * @psalm-var class-string
  45087. */
  45088. private readonly string $className;
  45089. /**
  45090. * @psalm-var non-empty-string
  45091. */
  45092. private readonly string $methodName;
  45093. /**
  45094. * @psalm-var non-negative-int
  45095. */
  45096. private readonly int $line;
  45097. private readonly \PHPUnit\Event\Code\TestDox $testDox;
  45098. private readonly MetadataCollection $metadata;
  45099. private readonly TestDataCollection $testData;
  45100. /**
  45101. * @psalm-param class-string $className
  45102. * @psalm-param non-empty-string $methodName
  45103. * @psalm-param non-empty-string $file
  45104. * @psalm-param non-negative-int $line
  45105. */
  45106. public function __construct(string $className, string $methodName, string $file, int $line, \PHPUnit\Event\Code\TestDox $testDox, MetadataCollection $metadata, TestDataCollection $testData)
  45107. {
  45108. parent::__construct($file);
  45109. $this->className = $className;
  45110. $this->methodName = $methodName;
  45111. $this->line = $line;
  45112. $this->testDox = $testDox;
  45113. $this->metadata = $metadata;
  45114. $this->testData = $testData;
  45115. }
  45116. /**
  45117. * @psalm-return class-string
  45118. */
  45119. public function className(): string
  45120. {
  45121. return $this->className;
  45122. }
  45123. /**
  45124. * @psalm-return non-empty-string
  45125. */
  45126. public function methodName(): string
  45127. {
  45128. return $this->methodName;
  45129. }
  45130. /**
  45131. * @psalm-return non-negative-int
  45132. */
  45133. public function line(): int
  45134. {
  45135. return $this->line;
  45136. }
  45137. public function testDox(): \PHPUnit\Event\Code\TestDox
  45138. {
  45139. return $this->testDox;
  45140. }
  45141. public function metadata(): MetadataCollection
  45142. {
  45143. return $this->metadata;
  45144. }
  45145. public function testData(): TestDataCollection
  45146. {
  45147. return $this->testData;
  45148. }
  45149. /**
  45150. * @psalm-assert-if-true TestMethod $this
  45151. */
  45152. public function isTestMethod(): bool
  45153. {
  45154. return \true;
  45155. }
  45156. /**
  45157. * @psalm-return non-empty-string
  45158. */
  45159. public function id(): string
  45160. {
  45161. $buffer = $this->className . '::' . $this->methodName;
  45162. if ($this->testData()->hasDataFromDataProvider()) {
  45163. $buffer .= '#' . $this->testData->dataFromDataProvider()->dataSetName();
  45164. }
  45165. return $buffer;
  45166. }
  45167. /**
  45168. * @psalm-return non-empty-string
  45169. */
  45170. public function nameWithClass(): string
  45171. {
  45172. return $this->className . '::' . $this->name();
  45173. }
  45174. /**
  45175. * @psalm-return non-empty-string
  45176. */
  45177. public function name(): string
  45178. {
  45179. if (!$this->testData->hasDataFromDataProvider()) {
  45180. return $this->methodName;
  45181. }
  45182. $dataSetName = $this->testData->dataFromDataProvider()->dataSetName();
  45183. if (is_int($dataSetName)) {
  45184. $dataSetName = sprintf(' with data set #%d', $dataSetName);
  45185. } else {
  45186. $dataSetName = sprintf(' with data set "%s"', $dataSetName);
  45187. }
  45188. return $this->methodName . $dataSetName;
  45189. }
  45190. }
  45191. <?php
  45192. declare (strict_types=1);
  45193. /*
  45194. * This file is part of PHPUnit.
  45195. *
  45196. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45197. *
  45198. * For the full copyright and license information, please view the LICENSE
  45199. * file that was distributed with this source code.
  45200. */
  45201. namespace PHPUnit\Event\Code;
  45202. use const DEBUG_BACKTRACE_IGNORE_ARGS;
  45203. use const DEBUG_BACKTRACE_PROVIDE_OBJECT;
  45204. use function assert;
  45205. use function debug_backtrace;
  45206. use function is_numeric;
  45207. use PHPUnit\Event\Facade as EventFacade;
  45208. use PHPUnit\Event\TestData\DataFromDataProvider;
  45209. use PHPUnit\Event\TestData\DataFromTestDependency;
  45210. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  45211. use PHPUnit\Event\TestData\TestDataCollection;
  45212. use PHPUnit\Framework\TestCase;
  45213. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  45214. use PHPUnit\Util\Exporter;
  45215. use PHPUnit\Util\Reflection;
  45216. /**
  45217. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45218. *
  45219. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  45220. */
  45221. final class TestMethodBuilder
  45222. {
  45223. /**
  45224. * @throws MoreThanOneDataSetFromDataProviderException
  45225. */
  45226. public static function fromTestCase(TestCase $testCase): \PHPUnit\Event\Code\TestMethod
  45227. {
  45228. $methodName = $testCase->name();
  45229. assert(!empty($methodName));
  45230. $location = Reflection::sourceLocationFor($testCase::class, $methodName);
  45231. return new \PHPUnit\Event\Code\TestMethod($testCase::class, $methodName, $location['file'], $location['line'], \PHPUnit\Event\Code\TestDoxBuilder::fromTestCase($testCase), MetadataRegistry::parser()->forClassAndMethod($testCase::class, $methodName), self::dataFor($testCase));
  45232. }
  45233. /**
  45234. * @throws NoTestCaseObjectOnCallStackException
  45235. */
  45236. public static function fromCallStack(): \PHPUnit\Event\Code\TestMethod
  45237. {
  45238. foreach (debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
  45239. if (isset($frame['object']) && $frame['object'] instanceof TestCase) {
  45240. return $frame['object']->valueObjectForEvents();
  45241. }
  45242. }
  45243. throw new \PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException();
  45244. }
  45245. /**
  45246. * @throws MoreThanOneDataSetFromDataProviderException
  45247. */
  45248. private static function dataFor(TestCase $testCase): TestDataCollection
  45249. {
  45250. $testData = [];
  45251. if ($testCase->usesDataProvider()) {
  45252. $dataSetName = $testCase->dataName();
  45253. if (is_numeric($dataSetName)) {
  45254. $dataSetName = (int) $dataSetName;
  45255. }
  45256. $testData[] = DataFromDataProvider::from($dataSetName, Exporter::export($testCase->providedData(), EventFacade::emitter()->exportsObjects()), $testCase->dataSetAsStringWithData());
  45257. }
  45258. if ($testCase->hasDependencyInput()) {
  45259. $testData[] = DataFromTestDependency::from(Exporter::export($testCase->dependencyInput(), EventFacade::emitter()->exportsObjects()));
  45260. }
  45261. return TestDataCollection::fromArray($testData);
  45262. }
  45263. }
  45264. <?php
  45265. declare (strict_types=1);
  45266. /*
  45267. * This file is part of PHPUnit.
  45268. *
  45269. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45270. *
  45271. * For the full copyright and license information, please view the LICENSE
  45272. * file that was distributed with this source code.
  45273. */
  45274. namespace PHPUnit\Event\TestSuite;
  45275. use PHPUnit\Event\Code\TestCollection;
  45276. /**
  45277. * @psalm-immutable
  45278. *
  45279. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45280. */
  45281. abstract class TestSuite
  45282. {
  45283. /**
  45284. * @psalm-var non-empty-string
  45285. */
  45286. private readonly string $name;
  45287. private readonly int $count;
  45288. private readonly TestCollection $tests;
  45289. /**
  45290. * @psalm-param non-empty-string $name
  45291. */
  45292. public function __construct(string $name, int $size, TestCollection $tests)
  45293. {
  45294. $this->name = $name;
  45295. $this->count = $size;
  45296. $this->tests = $tests;
  45297. }
  45298. /**
  45299. * @psalm-return non-empty-string
  45300. */
  45301. public function name(): string
  45302. {
  45303. return $this->name;
  45304. }
  45305. public function count(): int
  45306. {
  45307. return $this->count;
  45308. }
  45309. public function tests(): TestCollection
  45310. {
  45311. return $this->tests;
  45312. }
  45313. /**
  45314. * @psalm-assert-if-true TestSuiteWithName $this
  45315. */
  45316. public function isWithName(): bool
  45317. {
  45318. return \false;
  45319. }
  45320. /**
  45321. * @psalm-assert-if-true TestSuiteForTestClass $this
  45322. */
  45323. public function isForTestClass(): bool
  45324. {
  45325. return \false;
  45326. }
  45327. /**
  45328. * @psalm-assert-if-true TestSuiteForTestMethodWithDataProvider $this
  45329. */
  45330. public function isForTestMethodWithDataProvider(): bool
  45331. {
  45332. return \false;
  45333. }
  45334. }
  45335. <?php
  45336. declare (strict_types=1);
  45337. /*
  45338. * This file is part of PHPUnit.
  45339. *
  45340. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45341. *
  45342. * For the full copyright and license information, please view the LICENSE
  45343. * file that was distributed with this source code.
  45344. */
  45345. namespace PHPUnit\Event\TestSuite;
  45346. use function explode;
  45347. use PHPUnit\Event\Code\Test;
  45348. use PHPUnit\Event\Code\TestCollection;
  45349. use PHPUnit\Event\RuntimeException;
  45350. use PHPUnit\Framework\DataProviderTestSuite;
  45351. use PHPUnit\Framework\TestCase;
  45352. use PHPUnit\Framework\TestSuite as FrameworkTestSuite;
  45353. use PHPUnit\Runner\PhptTestCase;
  45354. use ReflectionClass;
  45355. use ReflectionException;
  45356. use ReflectionMethod;
  45357. /**
  45358. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45359. *
  45360. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  45361. */
  45362. final class TestSuiteBuilder
  45363. {
  45364. /**
  45365. * @throws RuntimeException
  45366. */
  45367. public static function from(FrameworkTestSuite $testSuite): \PHPUnit\Event\TestSuite\TestSuite
  45368. {
  45369. $tests = [];
  45370. self::process($testSuite, $tests);
  45371. if ($testSuite instanceof DataProviderTestSuite) {
  45372. [$className, $methodName] = explode('::', $testSuite->name());
  45373. try {
  45374. $reflector = new ReflectionMethod($className, $methodName);
  45375. return new \PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $className, $methodName, $reflector->getFileName(), $reflector->getStartLine());
  45376. // @codeCoverageIgnoreStart
  45377. } catch (ReflectionException $e) {
  45378. throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
  45379. }
  45380. // @codeCoverageIgnoreEnd
  45381. }
  45382. if ($testSuite->isForTestClass()) {
  45383. try {
  45384. $reflector = new ReflectionClass($testSuite->name());
  45385. return new \PHPUnit\Event\TestSuite\TestSuiteForTestClass($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $reflector->getFileName(), $reflector->getStartLine());
  45386. // @codeCoverageIgnoreStart
  45387. } catch (ReflectionException $e) {
  45388. throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
  45389. }
  45390. // @codeCoverageIgnoreEnd
  45391. }
  45392. return new \PHPUnit\Event\TestSuite\TestSuiteWithName($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests));
  45393. }
  45394. /**
  45395. * @psalm-param list<Test> $tests
  45396. */
  45397. private static function process(FrameworkTestSuite $testSuite, array &$tests): void
  45398. {
  45399. foreach ($testSuite->getIterator() as $test) {
  45400. if ($test instanceof FrameworkTestSuite) {
  45401. self::process($test, $tests);
  45402. continue;
  45403. }
  45404. if ($test instanceof TestCase || $test instanceof PhptTestCase) {
  45405. $tests[] = $test->valueObjectForEvents();
  45406. }
  45407. }
  45408. }
  45409. }
  45410. <?php
  45411. declare (strict_types=1);
  45412. /*
  45413. * This file is part of PHPUnit.
  45414. *
  45415. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45416. *
  45417. * For the full copyright and license information, please view the LICENSE
  45418. * file that was distributed with this source code.
  45419. */
  45420. namespace PHPUnit\Event\TestSuite;
  45421. use PHPUnit\Event\Code\TestCollection;
  45422. /**
  45423. * @psalm-immutable
  45424. *
  45425. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45426. */
  45427. final class TestSuiteForTestClass extends \PHPUnit\Event\TestSuite\TestSuite
  45428. {
  45429. /**
  45430. * @psalm-var class-string
  45431. */
  45432. private readonly string $className;
  45433. private readonly string $file;
  45434. private readonly int $line;
  45435. /**
  45436. * @psalm-param class-string $name
  45437. */
  45438. public function __construct(string $name, int $size, TestCollection $tests, string $file, int $line)
  45439. {
  45440. parent::__construct($name, $size, $tests);
  45441. $this->className = $name;
  45442. $this->file = $file;
  45443. $this->line = $line;
  45444. }
  45445. /**
  45446. * @psalm-return class-string
  45447. */
  45448. public function className(): string
  45449. {
  45450. return $this->className;
  45451. }
  45452. public function file(): string
  45453. {
  45454. return $this->file;
  45455. }
  45456. public function line(): int
  45457. {
  45458. return $this->line;
  45459. }
  45460. /**
  45461. * @psalm-assert-if-true TestSuiteForTestClass $this
  45462. */
  45463. public function isForTestClass(): bool
  45464. {
  45465. return \true;
  45466. }
  45467. }
  45468. <?php
  45469. declare (strict_types=1);
  45470. /*
  45471. * This file is part of PHPUnit.
  45472. *
  45473. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45474. *
  45475. * For the full copyright and license information, please view the LICENSE
  45476. * file that was distributed with this source code.
  45477. */
  45478. namespace PHPUnit\Event\TestSuite;
  45479. use PHPUnit\Event\Code\TestCollection;
  45480. /**
  45481. * @psalm-immutable
  45482. *
  45483. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45484. */
  45485. final class TestSuiteForTestMethodWithDataProvider extends \PHPUnit\Event\TestSuite\TestSuite
  45486. {
  45487. /**
  45488. * @psalm-var class-string
  45489. */
  45490. private readonly string $className;
  45491. /**
  45492. * @psalm-var non-empty-string
  45493. */
  45494. private readonly string $methodName;
  45495. private readonly string $file;
  45496. private readonly int $line;
  45497. /**
  45498. * @psalm-param non-empty-string $name
  45499. * @psalm-param class-string $className
  45500. * @psalm-param non-empty-string $methodName
  45501. */
  45502. public function __construct(string $name, int $size, TestCollection $tests, string $className, string $methodName, string $file, int $line)
  45503. {
  45504. parent::__construct($name, $size, $tests);
  45505. $this->className = $className;
  45506. $this->methodName = $methodName;
  45507. $this->file = $file;
  45508. $this->line = $line;
  45509. }
  45510. /**
  45511. * @psalm-return class-string
  45512. */
  45513. public function className(): string
  45514. {
  45515. return $this->className;
  45516. }
  45517. /**
  45518. * @psalm-return non-empty-string
  45519. */
  45520. public function methodName(): string
  45521. {
  45522. return $this->methodName;
  45523. }
  45524. public function file(): string
  45525. {
  45526. return $this->file;
  45527. }
  45528. public function line(): int
  45529. {
  45530. return $this->line;
  45531. }
  45532. /**
  45533. * @psalm-assert-if-true TestSuiteForTestMethodWithDataProvider $this
  45534. */
  45535. public function isForTestMethodWithDataProvider(): bool
  45536. {
  45537. return \true;
  45538. }
  45539. }
  45540. <?php
  45541. declare (strict_types=1);
  45542. /*
  45543. * This file is part of PHPUnit.
  45544. *
  45545. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45546. *
  45547. * For the full copyright and license information, please view the LICENSE
  45548. * file that was distributed with this source code.
  45549. */
  45550. namespace PHPUnit\Event\TestSuite;
  45551. /**
  45552. * @psalm-immutable
  45553. *
  45554. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45555. */
  45556. final class TestSuiteWithName extends \PHPUnit\Event\TestSuite\TestSuite
  45557. {
  45558. /**
  45559. * @psalm-assert-if-true TestSuiteWithName $this
  45560. */
  45561. public function isWithName(): bool
  45562. {
  45563. return \true;
  45564. }
  45565. }
  45566. <?php
  45567. declare (strict_types=1);
  45568. /*
  45569. * This file is part of PHPUnit.
  45570. *
  45571. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45572. *
  45573. * For the full copyright and license information, please view the LICENSE
  45574. * file that was distributed with this source code.
  45575. */
  45576. namespace PHPUnit\Event\Code;
  45577. use const PHP_EOL;
  45578. use PHPUnit\Event\NoPreviousThrowableException;
  45579. /**
  45580. * @psalm-immutable
  45581. *
  45582. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45583. */
  45584. final class Throwable
  45585. {
  45586. /**
  45587. * @psalm-var class-string
  45588. */
  45589. private readonly string $className;
  45590. private readonly string $message;
  45591. private readonly string $description;
  45592. private readonly string $stackTrace;
  45593. private readonly ?\PHPUnit\Event\Code\Throwable $previous;
  45594. /**
  45595. * @psalm-param class-string $className
  45596. */
  45597. public function __construct(string $className, string $message, string $description, string $stackTrace, ?self $previous)
  45598. {
  45599. $this->className = $className;
  45600. $this->message = $message;
  45601. $this->description = $description;
  45602. $this->stackTrace = $stackTrace;
  45603. $this->previous = $previous;
  45604. }
  45605. /**
  45606. * @throws NoPreviousThrowableException
  45607. */
  45608. public function asString(): string
  45609. {
  45610. $buffer = $this->description();
  45611. if (!empty($this->stackTrace())) {
  45612. $buffer .= PHP_EOL . $this->stackTrace();
  45613. }
  45614. if ($this->hasPrevious()) {
  45615. $buffer .= PHP_EOL . 'Caused by' . PHP_EOL . $this->previous()->asString();
  45616. }
  45617. return $buffer;
  45618. }
  45619. /**
  45620. * @psalm-return class-string
  45621. */
  45622. public function className(): string
  45623. {
  45624. return $this->className;
  45625. }
  45626. public function message(): string
  45627. {
  45628. return $this->message;
  45629. }
  45630. public function description(): string
  45631. {
  45632. return $this->description;
  45633. }
  45634. public function stackTrace(): string
  45635. {
  45636. return $this->stackTrace;
  45637. }
  45638. /**
  45639. * @psalm-assert-if-true !null $this->previous
  45640. */
  45641. public function hasPrevious(): bool
  45642. {
  45643. return $this->previous !== null;
  45644. }
  45645. /**
  45646. * @throws NoPreviousThrowableException
  45647. */
  45648. public function previous(): self
  45649. {
  45650. if ($this->previous === null) {
  45651. throw new NoPreviousThrowableException();
  45652. }
  45653. return $this->previous;
  45654. }
  45655. }
  45656. <?php
  45657. declare (strict_types=1);
  45658. /*
  45659. * This file is part of PHPUnit.
  45660. *
  45661. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45662. *
  45663. * For the full copyright and license information, please view the LICENSE
  45664. * file that was distributed with this source code.
  45665. */
  45666. namespace PHPUnit\Event\Code;
  45667. use PHPUnit\Event\NoPreviousThrowableException;
  45668. use PHPUnit\Framework\Exception;
  45669. use PHPUnit\Util\Filter;
  45670. use PHPUnit\Util\ThrowableToStringMapper;
  45671. /**
  45672. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45673. *
  45674. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  45675. */
  45676. final class ThrowableBuilder
  45677. {
  45678. /**
  45679. * @throws Exception
  45680. * @throws NoPreviousThrowableException
  45681. */
  45682. public static function from(\Throwable $t): \PHPUnit\Event\Code\Throwable
  45683. {
  45684. $previous = $t->getPrevious();
  45685. if ($previous !== null) {
  45686. $previous = self::from($previous);
  45687. }
  45688. return new \PHPUnit\Event\Code\Throwable($t::class, $t->getMessage(), ThrowableToStringMapper::map($t), Filter::getFilteredStacktrace($t, \false), $previous);
  45689. }
  45690. }
  45691. <?php
  45692. declare (strict_types=1);
  45693. /*
  45694. * This file is part of PHPUnit.
  45695. *
  45696. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45697. *
  45698. * For the full copyright and license information, please view the LICENSE
  45699. * file that was distributed with this source code.
  45700. */
  45701. namespace PHPUnit;
  45702. use Throwable;
  45703. interface Exception extends Throwable
  45704. {
  45705. }
  45706. <?php
  45707. declare (strict_types=1);
  45708. /*
  45709. * This file is part of PHPUnit.
  45710. *
  45711. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  45712. *
  45713. * For the full copyright and license information, please view the LICENSE
  45714. * file that was distributed with this source code.
  45715. */
  45716. namespace PHPUnit\Framework;
  45717. use function class_exists;
  45718. use function count;
  45719. use function file_get_contents;
  45720. use function interface_exists;
  45721. use function is_bool;
  45722. use ArrayAccess;
  45723. use Countable;
  45724. use Generator;
  45725. use PHPUnit\Event;
  45726. use PHPUnit\Framework\Constraint\ArrayHasKey;
  45727. use PHPUnit\Framework\Constraint\Callback;
  45728. use PHPUnit\Framework\Constraint\Constraint;
  45729. use PHPUnit\Framework\Constraint\Count;
  45730. use PHPUnit\Framework\Constraint\DirectoryExists;
  45731. use PHPUnit\Framework\Constraint\FileExists;
  45732. use PHPUnit\Framework\Constraint\GreaterThan;
  45733. use PHPUnit\Framework\Constraint\IsAnything;
  45734. use PHPUnit\Framework\Constraint\IsEmpty;
  45735. use PHPUnit\Framework\Constraint\IsEqual;
  45736. use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
  45737. use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
  45738. use PHPUnit\Framework\Constraint\IsEqualWithDelta;
  45739. use PHPUnit\Framework\Constraint\IsFalse;
  45740. use PHPUnit\Framework\Constraint\IsFinite;
  45741. use PHPUnit\Framework\Constraint\IsIdentical;
  45742. use PHPUnit\Framework\Constraint\IsInfinite;
  45743. use PHPUnit\Framework\Constraint\IsInstanceOf;
  45744. use PHPUnit\Framework\Constraint\IsJson;
  45745. use PHPUnit\Framework\Constraint\IsList;
  45746. use PHPUnit\Framework\Constraint\IsNan;
  45747. use PHPUnit\Framework\Constraint\IsNull;
  45748. use PHPUnit\Framework\Constraint\IsReadable;
  45749. use PHPUnit\Framework\Constraint\IsTrue;
  45750. use PHPUnit\Framework\Constraint\IsType;
  45751. use PHPUnit\Framework\Constraint\IsWritable;
  45752. use PHPUnit\Framework\Constraint\JsonMatches;
  45753. use PHPUnit\Framework\Constraint\LessThan;
  45754. use PHPUnit\Framework\Constraint\LogicalAnd;
  45755. use PHPUnit\Framework\Constraint\LogicalNot;
  45756. use PHPUnit\Framework\Constraint\LogicalOr;
  45757. use PHPUnit\Framework\Constraint\LogicalXor;
  45758. use PHPUnit\Framework\Constraint\ObjectEquals;
  45759. use PHPUnit\Framework\Constraint\ObjectHasProperty;
  45760. use PHPUnit\Framework\Constraint\RegularExpression;
  45761. use PHPUnit\Framework\Constraint\SameSize;
  45762. use PHPUnit\Framework\Constraint\StringContains;
  45763. use PHPUnit\Framework\Constraint\StringEndsWith;
  45764. use PHPUnit\Framework\Constraint\StringEqualsStringIgnoringLineEndings;
  45765. use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
  45766. use PHPUnit\Framework\Constraint\StringStartsWith;
  45767. use PHPUnit\Framework\Constraint\TraversableContainsEqual;
  45768. use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
  45769. use PHPUnit\Framework\Constraint\TraversableContainsOnly;
  45770. use PHPUnit\Util\Xml\Loader as XmlLoader;
  45771. use PHPUnit\Util\Xml\XmlException;
  45772. /**
  45773. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  45774. */
  45775. abstract class Assert
  45776. {
  45777. private static int $count = 0;
  45778. /**
  45779. * Asserts that an array has a specified key.
  45780. *
  45781. * @throws Exception
  45782. * @throws ExpectationFailedException
  45783. */
  45784. final public static function assertArrayHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
  45785. {
  45786. $constraint = new ArrayHasKey($key);
  45787. static::assertThat($array, $constraint, $message);
  45788. }
  45789. /**
  45790. * Asserts that an array does not have a specified key.
  45791. *
  45792. * @throws Exception
  45793. * @throws ExpectationFailedException
  45794. */
  45795. final public static function assertArrayNotHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
  45796. {
  45797. $constraint = new LogicalNot(new ArrayHasKey($key));
  45798. static::assertThat($array, $constraint, $message);
  45799. }
  45800. /**
  45801. * @throws ExpectationFailedException
  45802. */
  45803. final public static function assertIsList(mixed $array, string $message = ''): void
  45804. {
  45805. static::assertThat($array, new IsList(), $message);
  45806. }
  45807. /**
  45808. * Asserts that a haystack contains a needle.
  45809. *
  45810. * @throws Exception
  45811. * @throws ExpectationFailedException
  45812. */
  45813. final public static function assertContains(mixed $needle, iterable $haystack, string $message = ''): void
  45814. {
  45815. $constraint = new TraversableContainsIdentical($needle);
  45816. static::assertThat($haystack, $constraint, $message);
  45817. }
  45818. /**
  45819. * @throws ExpectationFailedException
  45820. */
  45821. final public static function assertContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
  45822. {
  45823. $constraint = new TraversableContainsEqual($needle);
  45824. static::assertThat($haystack, $constraint, $message);
  45825. }
  45826. /**
  45827. * Asserts that a haystack does not contain a needle.
  45828. *
  45829. * @throws Exception
  45830. * @throws ExpectationFailedException
  45831. */
  45832. final public static function assertNotContains(mixed $needle, iterable $haystack, string $message = ''): void
  45833. {
  45834. $constraint = new LogicalNot(new TraversableContainsIdentical($needle));
  45835. static::assertThat($haystack, $constraint, $message);
  45836. }
  45837. /**
  45838. * @throws ExpectationFailedException
  45839. */
  45840. final public static function assertNotContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
  45841. {
  45842. $constraint = new LogicalNot(new TraversableContainsEqual($needle));
  45843. static::assertThat($haystack, $constraint, $message);
  45844. }
  45845. /**
  45846. * Asserts that a haystack contains only values of a given type.
  45847. *
  45848. * @throws Exception
  45849. * @throws ExpectationFailedException
  45850. */
  45851. final public static function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
  45852. {
  45853. if ($isNativeType === null) {
  45854. $isNativeType = self::isNativeType($type);
  45855. }
  45856. static::assertThat($haystack, new TraversableContainsOnly($type, $isNativeType), $message);
  45857. }
  45858. /**
  45859. * Asserts that a haystack contains only instances of a given class name.
  45860. *
  45861. * @throws Exception
  45862. * @throws ExpectationFailedException
  45863. */
  45864. final public static function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
  45865. {
  45866. static::assertThat($haystack, new TraversableContainsOnly($className, \false), $message);
  45867. }
  45868. /**
  45869. * Asserts that a haystack does not contain only values of a given type.
  45870. *
  45871. * @throws Exception
  45872. * @throws ExpectationFailedException
  45873. */
  45874. final public static function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
  45875. {
  45876. if ($isNativeType === null) {
  45877. $isNativeType = self::isNativeType($type);
  45878. }
  45879. static::assertThat($haystack, new LogicalNot(new TraversableContainsOnly($type, $isNativeType)), $message);
  45880. }
  45881. /**
  45882. * Asserts the number of elements of an array, Countable or Traversable.
  45883. *
  45884. * @throws Exception
  45885. * @throws ExpectationFailedException
  45886. * @throws GeneratorNotSupportedException
  45887. */
  45888. final public static function assertCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
  45889. {
  45890. if ($haystack instanceof Generator) {
  45891. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$haystack');
  45892. }
  45893. static::assertThat($haystack, new Count($expectedCount), $message);
  45894. }
  45895. /**
  45896. * Asserts the number of elements of an array, Countable or Traversable.
  45897. *
  45898. * @throws Exception
  45899. * @throws ExpectationFailedException
  45900. * @throws GeneratorNotSupportedException
  45901. */
  45902. final public static function assertNotCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
  45903. {
  45904. if ($haystack instanceof Generator) {
  45905. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$haystack');
  45906. }
  45907. $constraint = new LogicalNot(new Count($expectedCount));
  45908. static::assertThat($haystack, $constraint, $message);
  45909. }
  45910. /**
  45911. * Asserts that two variables are equal.
  45912. *
  45913. * @throws ExpectationFailedException
  45914. */
  45915. final public static function assertEquals(mixed $expected, mixed $actual, string $message = ''): void
  45916. {
  45917. $constraint = new IsEqual($expected);
  45918. static::assertThat($actual, $constraint, $message);
  45919. }
  45920. /**
  45921. * Asserts that two variables are equal (canonicalizing).
  45922. *
  45923. * @throws ExpectationFailedException
  45924. */
  45925. final public static function assertEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
  45926. {
  45927. $constraint = new IsEqualCanonicalizing($expected);
  45928. static::assertThat($actual, $constraint, $message);
  45929. }
  45930. /**
  45931. * Asserts that two variables are equal (ignoring case).
  45932. *
  45933. * @throws ExpectationFailedException
  45934. */
  45935. final public static function assertEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
  45936. {
  45937. $constraint = new IsEqualIgnoringCase($expected);
  45938. static::assertThat($actual, $constraint, $message);
  45939. }
  45940. /**
  45941. * Asserts that two variables are equal (with delta).
  45942. *
  45943. * @throws ExpectationFailedException
  45944. */
  45945. final public static function assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
  45946. {
  45947. $constraint = new IsEqualWithDelta($expected, $delta);
  45948. static::assertThat($actual, $constraint, $message);
  45949. }
  45950. /**
  45951. * Asserts that two variables are not equal.
  45952. *
  45953. * @throws ExpectationFailedException
  45954. */
  45955. final public static function assertNotEquals(mixed $expected, mixed $actual, string $message = ''): void
  45956. {
  45957. $constraint = new LogicalNot(new IsEqual($expected));
  45958. static::assertThat($actual, $constraint, $message);
  45959. }
  45960. /**
  45961. * Asserts that two variables are not equal (canonicalizing).
  45962. *
  45963. * @throws ExpectationFailedException
  45964. */
  45965. final public static function assertNotEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
  45966. {
  45967. $constraint = new LogicalNot(new IsEqualCanonicalizing($expected));
  45968. static::assertThat($actual, $constraint, $message);
  45969. }
  45970. /**
  45971. * Asserts that two variables are not equal (ignoring case).
  45972. *
  45973. * @throws ExpectationFailedException
  45974. */
  45975. final public static function assertNotEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
  45976. {
  45977. $constraint = new LogicalNot(new IsEqualIgnoringCase($expected));
  45978. static::assertThat($actual, $constraint, $message);
  45979. }
  45980. /**
  45981. * Asserts that two variables are not equal (with delta).
  45982. *
  45983. * @throws ExpectationFailedException
  45984. */
  45985. final public static function assertNotEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
  45986. {
  45987. $constraint = new LogicalNot(new IsEqualWithDelta($expected, $delta));
  45988. static::assertThat($actual, $constraint, $message);
  45989. }
  45990. /**
  45991. * @throws ExpectationFailedException
  45992. */
  45993. final public static function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
  45994. {
  45995. static::assertThat($actual, static::objectEquals($expected, $method), $message);
  45996. }
  45997. /**
  45998. * Asserts that a variable is empty.
  45999. *
  46000. * @throws ExpectationFailedException
  46001. * @throws GeneratorNotSupportedException
  46002. *
  46003. * @psalm-assert empty $actual
  46004. */
  46005. final public static function assertEmpty(mixed $actual, string $message = ''): void
  46006. {
  46007. if ($actual instanceof Generator) {
  46008. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
  46009. }
  46010. static::assertThat($actual, static::isEmpty(), $message);
  46011. }
  46012. /**
  46013. * Asserts that a variable is not empty.
  46014. *
  46015. * @throws ExpectationFailedException
  46016. * @throws GeneratorNotSupportedException
  46017. *
  46018. * @psalm-assert !empty $actual
  46019. */
  46020. final public static function assertNotEmpty(mixed $actual, string $message = ''): void
  46021. {
  46022. if ($actual instanceof Generator) {
  46023. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
  46024. }
  46025. static::assertThat($actual, static::logicalNot(static::isEmpty()), $message);
  46026. }
  46027. /**
  46028. * Asserts that a value is greater than another value.
  46029. *
  46030. * @throws ExpectationFailedException
  46031. */
  46032. final public static function assertGreaterThan(mixed $expected, mixed $actual, string $message = ''): void
  46033. {
  46034. static::assertThat($actual, static::greaterThan($expected), $message);
  46035. }
  46036. /**
  46037. * Asserts that a value is greater than or equal to another value.
  46038. *
  46039. * @throws ExpectationFailedException
  46040. */
  46041. final public static function assertGreaterThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
  46042. {
  46043. static::assertThat($actual, static::greaterThanOrEqual($expected), $message);
  46044. }
  46045. /**
  46046. * Asserts that a value is smaller than another value.
  46047. *
  46048. * @throws ExpectationFailedException
  46049. */
  46050. final public static function assertLessThan(mixed $expected, mixed $actual, string $message = ''): void
  46051. {
  46052. static::assertThat($actual, static::lessThan($expected), $message);
  46053. }
  46054. /**
  46055. * Asserts that a value is smaller than or equal to another value.
  46056. *
  46057. * @throws ExpectationFailedException
  46058. */
  46059. final public static function assertLessThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
  46060. {
  46061. static::assertThat($actual, static::lessThanOrEqual($expected), $message);
  46062. }
  46063. /**
  46064. * Asserts that the contents of one file is equal to the contents of another
  46065. * file.
  46066. *
  46067. * @throws ExpectationFailedException
  46068. */
  46069. final public static function assertFileEquals(string $expected, string $actual, string $message = ''): void
  46070. {
  46071. static::assertFileExists($expected, $message);
  46072. static::assertFileExists($actual, $message);
  46073. $constraint = new IsEqual(file_get_contents($expected));
  46074. static::assertThat(file_get_contents($actual), $constraint, $message);
  46075. }
  46076. /**
  46077. * Asserts that the contents of one file is equal to the contents of another
  46078. * file (canonicalizing).
  46079. *
  46080. * @throws ExpectationFailedException
  46081. */
  46082. final public static function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
  46083. {
  46084. static::assertFileExists($expected, $message);
  46085. static::assertFileExists($actual, $message);
  46086. $constraint = new IsEqualCanonicalizing(file_get_contents($expected));
  46087. static::assertThat(file_get_contents($actual), $constraint, $message);
  46088. }
  46089. /**
  46090. * Asserts that the contents of one file is equal to the contents of another
  46091. * file (ignoring case).
  46092. *
  46093. * @throws ExpectationFailedException
  46094. */
  46095. final public static function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
  46096. {
  46097. static::assertFileExists($expected, $message);
  46098. static::assertFileExists($actual, $message);
  46099. $constraint = new IsEqualIgnoringCase(file_get_contents($expected));
  46100. static::assertThat(file_get_contents($actual), $constraint, $message);
  46101. }
  46102. /**
  46103. * Asserts that the contents of one file is not equal to the contents of
  46104. * another file.
  46105. *
  46106. * @throws ExpectationFailedException
  46107. */
  46108. final public static function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
  46109. {
  46110. static::assertFileExists($expected, $message);
  46111. static::assertFileExists($actual, $message);
  46112. $constraint = new LogicalNot(new IsEqual(file_get_contents($expected)));
  46113. static::assertThat(file_get_contents($actual), $constraint, $message);
  46114. }
  46115. /**
  46116. * Asserts that the contents of one file is not equal to the contents of another
  46117. * file (canonicalizing).
  46118. *
  46119. * @throws ExpectationFailedException
  46120. */
  46121. final public static function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
  46122. {
  46123. static::assertFileExists($expected, $message);
  46124. static::assertFileExists($actual, $message);
  46125. $constraint = new LogicalNot(new IsEqualCanonicalizing(file_get_contents($expected)));
  46126. static::assertThat(file_get_contents($actual), $constraint, $message);
  46127. }
  46128. /**
  46129. * Asserts that the contents of one file is not equal to the contents of another
  46130. * file (ignoring case).
  46131. *
  46132. * @throws ExpectationFailedException
  46133. */
  46134. final public static function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
  46135. {
  46136. static::assertFileExists($expected, $message);
  46137. static::assertFileExists($actual, $message);
  46138. $constraint = new LogicalNot(new IsEqualIgnoringCase(file_get_contents($expected)));
  46139. static::assertThat(file_get_contents($actual), $constraint, $message);
  46140. }
  46141. /**
  46142. * Asserts that the contents of a string is equal
  46143. * to the contents of a file.
  46144. *
  46145. * @throws ExpectationFailedException
  46146. */
  46147. final public static function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
  46148. {
  46149. static::assertFileExists($expectedFile, $message);
  46150. $constraint = new IsEqual(file_get_contents($expectedFile));
  46151. static::assertThat($actualString, $constraint, $message);
  46152. }
  46153. /**
  46154. * Asserts that the contents of a string is equal
  46155. * to the contents of a file (canonicalizing).
  46156. *
  46157. * @throws ExpectationFailedException
  46158. */
  46159. final public static function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
  46160. {
  46161. static::assertFileExists($expectedFile, $message);
  46162. $constraint = new IsEqualCanonicalizing(file_get_contents($expectedFile));
  46163. static::assertThat($actualString, $constraint, $message);
  46164. }
  46165. /**
  46166. * Asserts that the contents of a string is equal
  46167. * to the contents of a file (ignoring case).
  46168. *
  46169. * @throws ExpectationFailedException
  46170. */
  46171. final public static function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
  46172. {
  46173. static::assertFileExists($expectedFile, $message);
  46174. $constraint = new IsEqualIgnoringCase(file_get_contents($expectedFile));
  46175. static::assertThat($actualString, $constraint, $message);
  46176. }
  46177. /**
  46178. * Asserts that the contents of a string is not equal
  46179. * to the contents of a file.
  46180. *
  46181. * @throws ExpectationFailedException
  46182. */
  46183. final public static function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
  46184. {
  46185. static::assertFileExists($expectedFile, $message);
  46186. $constraint = new LogicalNot(new IsEqual(file_get_contents($expectedFile)));
  46187. static::assertThat($actualString, $constraint, $message);
  46188. }
  46189. /**
  46190. * Asserts that the contents of a string is not equal
  46191. * to the contents of a file (canonicalizing).
  46192. *
  46193. * @throws ExpectationFailedException
  46194. */
  46195. final public static function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
  46196. {
  46197. static::assertFileExists($expectedFile, $message);
  46198. $constraint = new LogicalNot(new IsEqualCanonicalizing(file_get_contents($expectedFile)));
  46199. static::assertThat($actualString, $constraint, $message);
  46200. }
  46201. /**
  46202. * Asserts that the contents of a string is not equal
  46203. * to the contents of a file (ignoring case).
  46204. *
  46205. * @throws ExpectationFailedException
  46206. */
  46207. final public static function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
  46208. {
  46209. static::assertFileExists($expectedFile, $message);
  46210. $constraint = new LogicalNot(new IsEqualIgnoringCase(file_get_contents($expectedFile)));
  46211. static::assertThat($actualString, $constraint, $message);
  46212. }
  46213. /**
  46214. * Asserts that a file/dir is readable.
  46215. *
  46216. * @throws ExpectationFailedException
  46217. */
  46218. final public static function assertIsReadable(string $filename, string $message = ''): void
  46219. {
  46220. static::assertThat($filename, new IsReadable(), $message);
  46221. }
  46222. /**
  46223. * Asserts that a file/dir exists and is not readable.
  46224. *
  46225. * @throws ExpectationFailedException
  46226. */
  46227. final public static function assertIsNotReadable(string $filename, string $message = ''): void
  46228. {
  46229. static::assertThat($filename, new LogicalNot(new IsReadable()), $message);
  46230. }
  46231. /**
  46232. * Asserts that a file/dir exists and is writable.
  46233. *
  46234. * @throws ExpectationFailedException
  46235. */
  46236. final public static function assertIsWritable(string $filename, string $message = ''): void
  46237. {
  46238. static::assertThat($filename, new IsWritable(), $message);
  46239. }
  46240. /**
  46241. * Asserts that a file/dir exists and is not writable.
  46242. *
  46243. * @throws ExpectationFailedException
  46244. */
  46245. final public static function assertIsNotWritable(string $filename, string $message = ''): void
  46246. {
  46247. static::assertThat($filename, new LogicalNot(new IsWritable()), $message);
  46248. }
  46249. /**
  46250. * Asserts that a directory exists.
  46251. *
  46252. * @throws ExpectationFailedException
  46253. */
  46254. final public static function assertDirectoryExists(string $directory, string $message = ''): void
  46255. {
  46256. static::assertThat($directory, new DirectoryExists(), $message);
  46257. }
  46258. /**
  46259. * Asserts that a directory does not exist.
  46260. *
  46261. * @throws ExpectationFailedException
  46262. */
  46263. final public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
  46264. {
  46265. static::assertThat($directory, new LogicalNot(new DirectoryExists()), $message);
  46266. }
  46267. /**
  46268. * Asserts that a directory exists and is readable.
  46269. *
  46270. * @throws ExpectationFailedException
  46271. */
  46272. final public static function assertDirectoryIsReadable(string $directory, string $message = ''): void
  46273. {
  46274. self::assertDirectoryExists($directory, $message);
  46275. self::assertIsReadable($directory, $message);
  46276. }
  46277. /**
  46278. * Asserts that a directory exists and is not readable.
  46279. *
  46280. * @throws ExpectationFailedException
  46281. */
  46282. final public static function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
  46283. {
  46284. self::assertDirectoryExists($directory, $message);
  46285. self::assertIsNotReadable($directory, $message);
  46286. }
  46287. /**
  46288. * Asserts that a directory exists and is writable.
  46289. *
  46290. * @throws ExpectationFailedException
  46291. */
  46292. final public static function assertDirectoryIsWritable(string $directory, string $message = ''): void
  46293. {
  46294. self::assertDirectoryExists($directory, $message);
  46295. self::assertIsWritable($directory, $message);
  46296. }
  46297. /**
  46298. * Asserts that a directory exists and is not writable.
  46299. *
  46300. * @throws ExpectationFailedException
  46301. */
  46302. final public static function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
  46303. {
  46304. self::assertDirectoryExists($directory, $message);
  46305. self::assertIsNotWritable($directory, $message);
  46306. }
  46307. /**
  46308. * Asserts that a file exists.
  46309. *
  46310. * @throws ExpectationFailedException
  46311. */
  46312. final public static function assertFileExists(string $filename, string $message = ''): void
  46313. {
  46314. static::assertThat($filename, new FileExists(), $message);
  46315. }
  46316. /**
  46317. * Asserts that a file does not exist.
  46318. *
  46319. * @throws ExpectationFailedException
  46320. */
  46321. final public static function assertFileDoesNotExist(string $filename, string $message = ''): void
  46322. {
  46323. static::assertThat($filename, new LogicalNot(new FileExists()), $message);
  46324. }
  46325. /**
  46326. * Asserts that a file exists and is readable.
  46327. *
  46328. * @throws ExpectationFailedException
  46329. */
  46330. final public static function assertFileIsReadable(string $file, string $message = ''): void
  46331. {
  46332. self::assertFileExists($file, $message);
  46333. self::assertIsReadable($file, $message);
  46334. }
  46335. /**
  46336. * Asserts that a file exists and is not readable.
  46337. *
  46338. * @throws ExpectationFailedException
  46339. */
  46340. final public static function assertFileIsNotReadable(string $file, string $message = ''): void
  46341. {
  46342. self::assertFileExists($file, $message);
  46343. self::assertIsNotReadable($file, $message);
  46344. }
  46345. /**
  46346. * Asserts that a file exists and is writable.
  46347. *
  46348. * @throws ExpectationFailedException
  46349. */
  46350. final public static function assertFileIsWritable(string $file, string $message = ''): void
  46351. {
  46352. self::assertFileExists($file, $message);
  46353. self::assertIsWritable($file, $message);
  46354. }
  46355. /**
  46356. * Asserts that a file exists and is not writable.
  46357. *
  46358. * @throws ExpectationFailedException
  46359. */
  46360. final public static function assertFileIsNotWritable(string $file, string $message = ''): void
  46361. {
  46362. self::assertFileExists($file, $message);
  46363. self::assertIsNotWritable($file, $message);
  46364. }
  46365. /**
  46366. * Asserts that a condition is true.
  46367. *
  46368. * @throws ExpectationFailedException
  46369. *
  46370. * @psalm-assert true $condition
  46371. */
  46372. final public static function assertTrue(mixed $condition, string $message = ''): void
  46373. {
  46374. static::assertThat($condition, static::isTrue(), $message);
  46375. }
  46376. /**
  46377. * Asserts that a condition is not true.
  46378. *
  46379. * @throws ExpectationFailedException
  46380. *
  46381. * @psalm-assert !true $condition
  46382. */
  46383. final public static function assertNotTrue(mixed $condition, string $message = ''): void
  46384. {
  46385. static::assertThat($condition, static::logicalNot(static::isTrue()), $message);
  46386. }
  46387. /**
  46388. * Asserts that a condition is false.
  46389. *
  46390. * @throws ExpectationFailedException
  46391. *
  46392. * @psalm-assert false $condition
  46393. */
  46394. final public static function assertFalse(mixed $condition, string $message = ''): void
  46395. {
  46396. static::assertThat($condition, static::isFalse(), $message);
  46397. }
  46398. /**
  46399. * Asserts that a condition is not false.
  46400. *
  46401. * @throws ExpectationFailedException
  46402. *
  46403. * @psalm-assert !false $condition
  46404. */
  46405. final public static function assertNotFalse(mixed $condition, string $message = ''): void
  46406. {
  46407. static::assertThat($condition, static::logicalNot(static::isFalse()), $message);
  46408. }
  46409. /**
  46410. * Asserts that a variable is null.
  46411. *
  46412. * @throws ExpectationFailedException
  46413. *
  46414. * @psalm-assert null $actual
  46415. */
  46416. final public static function assertNull(mixed $actual, string $message = ''): void
  46417. {
  46418. static::assertThat($actual, static::isNull(), $message);
  46419. }
  46420. /**
  46421. * Asserts that a variable is not null.
  46422. *
  46423. * @throws ExpectationFailedException
  46424. *
  46425. * @psalm-assert !null $actual
  46426. */
  46427. final public static function assertNotNull(mixed $actual, string $message = ''): void
  46428. {
  46429. static::assertThat($actual, static::logicalNot(static::isNull()), $message);
  46430. }
  46431. /**
  46432. * Asserts that a variable is finite.
  46433. *
  46434. * @throws ExpectationFailedException
  46435. */
  46436. final public static function assertFinite(mixed $actual, string $message = ''): void
  46437. {
  46438. static::assertThat($actual, static::isFinite(), $message);
  46439. }
  46440. /**
  46441. * Asserts that a variable is infinite.
  46442. *
  46443. * @throws ExpectationFailedException
  46444. */
  46445. final public static function assertInfinite(mixed $actual, string $message = ''): void
  46446. {
  46447. static::assertThat($actual, static::isInfinite(), $message);
  46448. }
  46449. /**
  46450. * Asserts that a variable is nan.
  46451. *
  46452. * @throws ExpectationFailedException
  46453. */
  46454. final public static function assertNan(mixed $actual, string $message = ''): void
  46455. {
  46456. static::assertThat($actual, static::isNan(), $message);
  46457. }
  46458. /**
  46459. * Asserts that an object has a specified property.
  46460. *
  46461. * @throws ExpectationFailedException
  46462. */
  46463. final public static function assertObjectHasProperty(string $propertyName, object $object, string $message = ''): void
  46464. {
  46465. static::assertThat($object, new ObjectHasProperty($propertyName), $message);
  46466. }
  46467. /**
  46468. * Asserts that an object does not have a specified property.
  46469. *
  46470. * @throws ExpectationFailedException
  46471. */
  46472. final public static function assertObjectNotHasProperty(string $propertyName, object $object, string $message = ''): void
  46473. {
  46474. static::assertThat($object, new LogicalNot(new ObjectHasProperty($propertyName)), $message);
  46475. }
  46476. /**
  46477. * Asserts that two variables have the same type and value.
  46478. * Used on objects, it asserts that two variables reference
  46479. * the same object.
  46480. *
  46481. * @throws ExpectationFailedException
  46482. *
  46483. * @psalm-template ExpectedType
  46484. *
  46485. * @psalm-param ExpectedType $expected
  46486. *
  46487. * @psalm-assert =ExpectedType $actual
  46488. */
  46489. final public static function assertSame(mixed $expected, mixed $actual, string $message = ''): void
  46490. {
  46491. static::assertThat($actual, new IsIdentical($expected), $message);
  46492. }
  46493. /**
  46494. * Asserts that two variables do not have the same type and value.
  46495. * Used on objects, it asserts that two variables do not reference
  46496. * the same object.
  46497. *
  46498. * @throws ExpectationFailedException
  46499. */
  46500. final public static function assertNotSame(mixed $expected, mixed $actual, string $message = ''): void
  46501. {
  46502. if (is_bool($expected) && is_bool($actual)) {
  46503. static::assertNotEquals($expected, $actual, $message);
  46504. }
  46505. static::assertThat($actual, new LogicalNot(new IsIdentical($expected)), $message);
  46506. }
  46507. /**
  46508. * Asserts that a variable is of a given type.
  46509. *
  46510. * @throws Exception
  46511. * @throws ExpectationFailedException
  46512. * @throws UnknownClassOrInterfaceException
  46513. *
  46514. * @psalm-template ExpectedType of object
  46515. *
  46516. * @psalm-param class-string<ExpectedType> $expected
  46517. *
  46518. * @psalm-assert =ExpectedType $actual
  46519. */
  46520. final public static function assertInstanceOf(string $expected, mixed $actual, string $message = ''): void
  46521. {
  46522. if (!class_exists($expected) && !interface_exists($expected)) {
  46523. throw new \PHPUnit\Framework\UnknownClassOrInterfaceException($expected);
  46524. }
  46525. static::assertThat($actual, new IsInstanceOf($expected), $message);
  46526. }
  46527. /**
  46528. * Asserts that a variable is not of a given type.
  46529. *
  46530. * @throws Exception
  46531. * @throws ExpectationFailedException
  46532. *
  46533. * @psalm-template ExpectedType of object
  46534. *
  46535. * @psalm-param class-string<ExpectedType> $expected
  46536. *
  46537. * @psalm-assert !ExpectedType $actual
  46538. */
  46539. final public static function assertNotInstanceOf(string $expected, mixed $actual, string $message = ''): void
  46540. {
  46541. if (!class_exists($expected) && !interface_exists($expected)) {
  46542. throw new \PHPUnit\Framework\UnknownClassOrInterfaceException($expected);
  46543. }
  46544. static::assertThat($actual, new LogicalNot(new IsInstanceOf($expected)), $message);
  46545. }
  46546. /**
  46547. * Asserts that a variable is of type array.
  46548. *
  46549. * @throws Exception
  46550. * @throws ExpectationFailedException
  46551. *
  46552. * @psalm-assert array $actual
  46553. */
  46554. final public static function assertIsArray(mixed $actual, string $message = ''): void
  46555. {
  46556. static::assertThat($actual, new IsType(IsType::TYPE_ARRAY), $message);
  46557. }
  46558. /**
  46559. * Asserts that a variable is of type bool.
  46560. *
  46561. * @throws Exception
  46562. * @throws ExpectationFailedException
  46563. *
  46564. * @psalm-assert bool $actual
  46565. */
  46566. final public static function assertIsBool(mixed $actual, string $message = ''): void
  46567. {
  46568. static::assertThat($actual, new IsType(IsType::TYPE_BOOL), $message);
  46569. }
  46570. /**
  46571. * Asserts that a variable is of type float.
  46572. *
  46573. * @throws Exception
  46574. * @throws ExpectationFailedException
  46575. *
  46576. * @psalm-assert float $actual
  46577. */
  46578. final public static function assertIsFloat(mixed $actual, string $message = ''): void
  46579. {
  46580. static::assertThat($actual, new IsType(IsType::TYPE_FLOAT), $message);
  46581. }
  46582. /**
  46583. * Asserts that a variable is of type int.
  46584. *
  46585. * @throws Exception
  46586. * @throws ExpectationFailedException
  46587. *
  46588. * @psalm-assert int $actual
  46589. */
  46590. final public static function assertIsInt(mixed $actual, string $message = ''): void
  46591. {
  46592. static::assertThat($actual, new IsType(IsType::TYPE_INT), $message);
  46593. }
  46594. /**
  46595. * Asserts that a variable is of type numeric.
  46596. *
  46597. * @throws Exception
  46598. * @throws ExpectationFailedException
  46599. *
  46600. * @psalm-assert numeric $actual
  46601. */
  46602. final public static function assertIsNumeric(mixed $actual, string $message = ''): void
  46603. {
  46604. static::assertThat($actual, new IsType(IsType::TYPE_NUMERIC), $message);
  46605. }
  46606. /**
  46607. * Asserts that a variable is of type object.
  46608. *
  46609. * @throws Exception
  46610. * @throws ExpectationFailedException
  46611. *
  46612. * @psalm-assert object $actual
  46613. */
  46614. final public static function assertIsObject(mixed $actual, string $message = ''): void
  46615. {
  46616. static::assertThat($actual, new IsType(IsType::TYPE_OBJECT), $message);
  46617. }
  46618. /**
  46619. * Asserts that a variable is of type resource.
  46620. *
  46621. * @throws Exception
  46622. * @throws ExpectationFailedException
  46623. *
  46624. * @psalm-assert resource $actual
  46625. */
  46626. final public static function assertIsResource(mixed $actual, string $message = ''): void
  46627. {
  46628. static::assertThat($actual, new IsType(IsType::TYPE_RESOURCE), $message);
  46629. }
  46630. /**
  46631. * Asserts that a variable is of type resource and is closed.
  46632. *
  46633. * @throws Exception
  46634. * @throws ExpectationFailedException
  46635. *
  46636. * @psalm-assert resource $actual
  46637. */
  46638. final public static function assertIsClosedResource(mixed $actual, string $message = ''): void
  46639. {
  46640. static::assertThat($actual, new IsType(IsType::TYPE_CLOSED_RESOURCE), $message);
  46641. }
  46642. /**
  46643. * Asserts that a variable is of type string.
  46644. *
  46645. * @throws Exception
  46646. * @throws ExpectationFailedException
  46647. *
  46648. * @psalm-assert string $actual
  46649. */
  46650. final public static function assertIsString(mixed $actual, string $message = ''): void
  46651. {
  46652. static::assertThat($actual, new IsType(IsType::TYPE_STRING), $message);
  46653. }
  46654. /**
  46655. * Asserts that a variable is of type scalar.
  46656. *
  46657. * @throws Exception
  46658. * @throws ExpectationFailedException
  46659. *
  46660. * @psalm-assert scalar $actual
  46661. */
  46662. final public static function assertIsScalar(mixed $actual, string $message = ''): void
  46663. {
  46664. static::assertThat($actual, new IsType(IsType::TYPE_SCALAR), $message);
  46665. }
  46666. /**
  46667. * Asserts that a variable is of type callable.
  46668. *
  46669. * @throws Exception
  46670. * @throws ExpectationFailedException
  46671. *
  46672. * @psalm-assert callable $actual
  46673. */
  46674. final public static function assertIsCallable(mixed $actual, string $message = ''): void
  46675. {
  46676. static::assertThat($actual, new IsType(IsType::TYPE_CALLABLE), $message);
  46677. }
  46678. /**
  46679. * Asserts that a variable is of type iterable.
  46680. *
  46681. * @throws Exception
  46682. * @throws ExpectationFailedException
  46683. *
  46684. * @psalm-assert iterable $actual
  46685. */
  46686. final public static function assertIsIterable(mixed $actual, string $message = ''): void
  46687. {
  46688. static::assertThat($actual, new IsType(IsType::TYPE_ITERABLE), $message);
  46689. }
  46690. /**
  46691. * Asserts that a variable is not of type array.
  46692. *
  46693. * @throws Exception
  46694. * @throws ExpectationFailedException
  46695. *
  46696. * @psalm-assert !array $actual
  46697. */
  46698. final public static function assertIsNotArray(mixed $actual, string $message = ''): void
  46699. {
  46700. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_ARRAY)), $message);
  46701. }
  46702. /**
  46703. * Asserts that a variable is not of type bool.
  46704. *
  46705. * @throws Exception
  46706. * @throws ExpectationFailedException
  46707. *
  46708. * @psalm-assert !bool $actual
  46709. */
  46710. final public static function assertIsNotBool(mixed $actual, string $message = ''): void
  46711. {
  46712. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_BOOL)), $message);
  46713. }
  46714. /**
  46715. * Asserts that a variable is not of type float.
  46716. *
  46717. * @throws Exception
  46718. * @throws ExpectationFailedException
  46719. *
  46720. * @psalm-assert !float $actual
  46721. */
  46722. final public static function assertIsNotFloat(mixed $actual, string $message = ''): void
  46723. {
  46724. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_FLOAT)), $message);
  46725. }
  46726. /**
  46727. * Asserts that a variable is not of type int.
  46728. *
  46729. * @throws Exception
  46730. * @throws ExpectationFailedException
  46731. *
  46732. * @psalm-assert !int $actual
  46733. */
  46734. final public static function assertIsNotInt(mixed $actual, string $message = ''): void
  46735. {
  46736. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_INT)), $message);
  46737. }
  46738. /**
  46739. * Asserts that a variable is not of type numeric.
  46740. *
  46741. * @throws Exception
  46742. * @throws ExpectationFailedException
  46743. *
  46744. * @psalm-assert !numeric $actual
  46745. */
  46746. final public static function assertIsNotNumeric(mixed $actual, string $message = ''): void
  46747. {
  46748. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_NUMERIC)), $message);
  46749. }
  46750. /**
  46751. * Asserts that a variable is not of type object.
  46752. *
  46753. * @throws Exception
  46754. * @throws ExpectationFailedException
  46755. *
  46756. * @psalm-assert !object $actual
  46757. */
  46758. final public static function assertIsNotObject(mixed $actual, string $message = ''): void
  46759. {
  46760. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_OBJECT)), $message);
  46761. }
  46762. /**
  46763. * Asserts that a variable is not of type resource.
  46764. *
  46765. * @throws Exception
  46766. * @throws ExpectationFailedException
  46767. *
  46768. * @psalm-assert !resource $actual
  46769. */
  46770. final public static function assertIsNotResource(mixed $actual, string $message = ''): void
  46771. {
  46772. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_RESOURCE)), $message);
  46773. }
  46774. /**
  46775. * Asserts that a variable is not of type resource.
  46776. *
  46777. * @throws Exception
  46778. * @throws ExpectationFailedException
  46779. *
  46780. * @psalm-assert !resource $actual
  46781. */
  46782. final public static function assertIsNotClosedResource(mixed $actual, string $message = ''): void
  46783. {
  46784. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_CLOSED_RESOURCE)), $message);
  46785. }
  46786. /**
  46787. * Asserts that a variable is not of type string.
  46788. *
  46789. * @throws Exception
  46790. * @throws ExpectationFailedException
  46791. *
  46792. * @psalm-assert !string $actual
  46793. */
  46794. final public static function assertIsNotString(mixed $actual, string $message = ''): void
  46795. {
  46796. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_STRING)), $message);
  46797. }
  46798. /**
  46799. * Asserts that a variable is not of type scalar.
  46800. *
  46801. * @throws Exception
  46802. * @throws ExpectationFailedException
  46803. *
  46804. * @psalm-assert !scalar $actual
  46805. */
  46806. final public static function assertIsNotScalar(mixed $actual, string $message = ''): void
  46807. {
  46808. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_SCALAR)), $message);
  46809. }
  46810. /**
  46811. * Asserts that a variable is not of type callable.
  46812. *
  46813. * @throws Exception
  46814. * @throws ExpectationFailedException
  46815. *
  46816. * @psalm-assert !callable $actual
  46817. */
  46818. final public static function assertIsNotCallable(mixed $actual, string $message = ''): void
  46819. {
  46820. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_CALLABLE)), $message);
  46821. }
  46822. /**
  46823. * Asserts that a variable is not of type iterable.
  46824. *
  46825. * @throws Exception
  46826. * @throws ExpectationFailedException
  46827. *
  46828. * @psalm-assert !iterable $actual
  46829. */
  46830. final public static function assertIsNotIterable(mixed $actual, string $message = ''): void
  46831. {
  46832. static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_ITERABLE)), $message);
  46833. }
  46834. /**
  46835. * Asserts that a string matches a given regular expression.
  46836. *
  46837. * @throws ExpectationFailedException
  46838. */
  46839. final public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
  46840. {
  46841. static::assertThat($string, new RegularExpression($pattern), $message);
  46842. }
  46843. /**
  46844. * Asserts that a string does not match a given regular expression.
  46845. *
  46846. * @throws ExpectationFailedException
  46847. */
  46848. final public static function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
  46849. {
  46850. static::assertThat($string, new LogicalNot(new RegularExpression($pattern)), $message);
  46851. }
  46852. /**
  46853. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  46854. * is the same.
  46855. *
  46856. * @throws Exception
  46857. * @throws ExpectationFailedException
  46858. * @throws GeneratorNotSupportedException
  46859. */
  46860. final public static function assertSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
  46861. {
  46862. if ($expected instanceof Generator) {
  46863. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$expected');
  46864. }
  46865. if ($actual instanceof Generator) {
  46866. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
  46867. }
  46868. static::assertThat($actual, new SameSize($expected), $message);
  46869. }
  46870. /**
  46871. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  46872. * is not the same.
  46873. *
  46874. * @throws Exception
  46875. * @throws ExpectationFailedException
  46876. * @throws GeneratorNotSupportedException
  46877. */
  46878. final public static function assertNotSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
  46879. {
  46880. if ($expected instanceof Generator) {
  46881. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$expected');
  46882. }
  46883. if ($actual instanceof Generator) {
  46884. throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
  46885. }
  46886. static::assertThat($actual, new LogicalNot(new SameSize($expected)), $message);
  46887. }
  46888. /**
  46889. * @throws ExpectationFailedException
  46890. */
  46891. final public static function assertStringContainsStringIgnoringLineEndings(string $needle, string $haystack, string $message = ''): void
  46892. {
  46893. static::assertThat($haystack, new StringContains($needle, \false, \true), $message);
  46894. }
  46895. /**
  46896. * Asserts that two strings are equal except for line endings.
  46897. *
  46898. * @throws ExpectationFailedException
  46899. */
  46900. final public static function assertStringEqualsStringIgnoringLineEndings(string $expected, string $actual, string $message = ''): void
  46901. {
  46902. static::assertThat($actual, new StringEqualsStringIgnoringLineEndings($expected), $message);
  46903. }
  46904. /**
  46905. * Asserts that a string matches a given format string.
  46906. *
  46907. * @throws ExpectationFailedException
  46908. */
  46909. final public static function assertFileMatchesFormat(string $format, string $actualFile, string $message = ''): void
  46910. {
  46911. static::assertFileExists($actualFile, $message);
  46912. static::assertThat(file_get_contents($actualFile), new StringMatchesFormatDescription($format), $message);
  46913. }
  46914. /**
  46915. * Asserts that a string matches a given format string.
  46916. *
  46917. * @throws ExpectationFailedException
  46918. */
  46919. final public static function assertFileMatchesFormatFile(string $formatFile, string $actualFile, string $message = ''): void
  46920. {
  46921. static::assertFileExists($formatFile, $message);
  46922. static::assertFileExists($actualFile, $message);
  46923. static::assertThat(file_get_contents($actualFile), new StringMatchesFormatDescription(file_get_contents($formatFile)), $message);
  46924. }
  46925. /**
  46926. * Asserts that a string matches a given format string.
  46927. *
  46928. * @throws ExpectationFailedException
  46929. */
  46930. final public static function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
  46931. {
  46932. static::assertThat($string, new StringMatchesFormatDescription($format), $message);
  46933. }
  46934. /**
  46935. * Asserts that a string does not match a given format string.
  46936. *
  46937. * @throws ExpectationFailedException
  46938. *
  46939. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
  46940. */
  46941. final public static function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
  46942. {
  46943. static::assertThat($string, new LogicalNot(new StringMatchesFormatDescription($format)), $message);
  46944. }
  46945. /**
  46946. * Asserts that a string matches a given format file.
  46947. *
  46948. * @throws ExpectationFailedException
  46949. */
  46950. final public static function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
  46951. {
  46952. static::assertFileExists($formatFile, $message);
  46953. static::assertThat($string, new StringMatchesFormatDescription(file_get_contents($formatFile)), $message);
  46954. }
  46955. /**
  46956. * Asserts that a string does not match a given format string.
  46957. *
  46958. * @throws ExpectationFailedException
  46959. *
  46960. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
  46961. */
  46962. final public static function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
  46963. {
  46964. static::assertFileExists($formatFile, $message);
  46965. static::assertThat($string, new LogicalNot(new StringMatchesFormatDescription(file_get_contents($formatFile))), $message);
  46966. }
  46967. /**
  46968. * Asserts that a string starts with a given prefix.
  46969. *
  46970. * @psalm-param non-empty-string $prefix
  46971. *
  46972. * @throws ExpectationFailedException
  46973. * @throws InvalidArgumentException
  46974. */
  46975. final public static function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
  46976. {
  46977. static::assertThat($string, new StringStartsWith($prefix), $message);
  46978. }
  46979. /**
  46980. * Asserts that a string starts not with a given prefix.
  46981. *
  46982. * @psalm-param non-empty-string $prefix
  46983. *
  46984. * @throws ExpectationFailedException
  46985. * @throws InvalidArgumentException
  46986. */
  46987. final public static function assertStringStartsNotWith(string $prefix, string $string, string $message = ''): void
  46988. {
  46989. static::assertThat($string, new LogicalNot(new StringStartsWith($prefix)), $message);
  46990. }
  46991. /**
  46992. * @throws ExpectationFailedException
  46993. */
  46994. final public static function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
  46995. {
  46996. $constraint = new StringContains($needle);
  46997. static::assertThat($haystack, $constraint, $message);
  46998. }
  46999. /**
  47000. * @throws ExpectationFailedException
  47001. */
  47002. final public static function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
  47003. {
  47004. $constraint = new StringContains($needle, \true);
  47005. static::assertThat($haystack, $constraint, $message);
  47006. }
  47007. /**
  47008. * @throws ExpectationFailedException
  47009. */
  47010. final public static function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
  47011. {
  47012. $constraint = new LogicalNot(new StringContains($needle));
  47013. static::assertThat($haystack, $constraint, $message);
  47014. }
  47015. /**
  47016. * @throws ExpectationFailedException
  47017. */
  47018. final public static function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
  47019. {
  47020. $constraint = new LogicalNot(new StringContains($needle, \true));
  47021. static::assertThat($haystack, $constraint, $message);
  47022. }
  47023. /**
  47024. * Asserts that a string ends with a given suffix.
  47025. *
  47026. * @psalm-param non-empty-string $suffix
  47027. *
  47028. * @throws ExpectationFailedException
  47029. * @throws InvalidArgumentException
  47030. */
  47031. final public static function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
  47032. {
  47033. static::assertThat($string, new StringEndsWith($suffix), $message);
  47034. }
  47035. /**
  47036. * Asserts that a string ends not with a given suffix.
  47037. *
  47038. * @psalm-param non-empty-string $suffix
  47039. *
  47040. * @throws ExpectationFailedException
  47041. * @throws InvalidArgumentException
  47042. */
  47043. final public static function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
  47044. {
  47045. static::assertThat($string, new LogicalNot(new StringEndsWith($suffix)), $message);
  47046. }
  47047. /**
  47048. * Asserts that two XML files are equal.
  47049. *
  47050. * @throws Exception
  47051. * @throws ExpectationFailedException
  47052. * @throws XmlException
  47053. */
  47054. final public static function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
  47055. {
  47056. $expected = (new XmlLoader())->loadFile($expectedFile);
  47057. $actual = (new XmlLoader())->loadFile($actualFile);
  47058. static::assertEquals($expected, $actual, $message);
  47059. }
  47060. /**
  47061. * Asserts that two XML files are not equal.
  47062. *
  47063. * @throws \PHPUnit\Util\Exception
  47064. * @throws ExpectationFailedException
  47065. */
  47066. final public static function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
  47067. {
  47068. $expected = (new XmlLoader())->loadFile($expectedFile);
  47069. $actual = (new XmlLoader())->loadFile($actualFile);
  47070. static::assertNotEquals($expected, $actual, $message);
  47071. }
  47072. /**
  47073. * Asserts that two XML documents are equal.
  47074. *
  47075. * @throws ExpectationFailedException
  47076. * @throws XmlException
  47077. */
  47078. final public static function assertXmlStringEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
  47079. {
  47080. $expected = (new XmlLoader())->loadFile($expectedFile);
  47081. $actual = (new XmlLoader())->load($actualXml);
  47082. static::assertEquals($expected, $actual, $message);
  47083. }
  47084. /**
  47085. * Asserts that two XML documents are not equal.
  47086. *
  47087. * @throws ExpectationFailedException
  47088. * @throws XmlException
  47089. */
  47090. final public static function assertXmlStringNotEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
  47091. {
  47092. $expected = (new XmlLoader())->loadFile($expectedFile);
  47093. $actual = (new XmlLoader())->load($actualXml);
  47094. static::assertNotEquals($expected, $actual, $message);
  47095. }
  47096. /**
  47097. * Asserts that two XML documents are equal.
  47098. *
  47099. * @throws ExpectationFailedException
  47100. * @throws XmlException
  47101. */
  47102. final public static function assertXmlStringEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
  47103. {
  47104. $expected = (new XmlLoader())->load($expectedXml);
  47105. $actual = (new XmlLoader())->load($actualXml);
  47106. static::assertEquals($expected, $actual, $message);
  47107. }
  47108. /**
  47109. * Asserts that two XML documents are not equal.
  47110. *
  47111. * @throws ExpectationFailedException
  47112. * @throws XmlException
  47113. */
  47114. final public static function assertXmlStringNotEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
  47115. {
  47116. $expected = (new XmlLoader())->load($expectedXml);
  47117. $actual = (new XmlLoader())->load($actualXml);
  47118. static::assertNotEquals($expected, $actual, $message);
  47119. }
  47120. /**
  47121. * Evaluates a PHPUnit\Framework\Constraint matcher object.
  47122. *
  47123. * @throws ExpectationFailedException
  47124. */
  47125. final public static function assertThat(mixed $value, Constraint $constraint, string $message = ''): void
  47126. {
  47127. self::$count += count($constraint);
  47128. $hasFailed = \true;
  47129. try {
  47130. $constraint->evaluate($value, $message);
  47131. $hasFailed = \false;
  47132. } finally {
  47133. if ($hasFailed) {
  47134. Event\Facade::emitter()->testAssertionFailed($value, $constraint, $message);
  47135. } else {
  47136. Event\Facade::emitter()->testAssertionSucceeded($value, $constraint, $message);
  47137. }
  47138. }
  47139. }
  47140. /**
  47141. * Asserts that a string is a valid JSON string.
  47142. *
  47143. * @throws ExpectationFailedException
  47144. */
  47145. final public static function assertJson(string $actual, string $message = ''): void
  47146. {
  47147. static::assertThat($actual, static::isJson(), $message);
  47148. }
  47149. /**
  47150. * Asserts that two given JSON encoded objects or arrays are equal.
  47151. *
  47152. * @throws ExpectationFailedException
  47153. */
  47154. final public static function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
  47155. {
  47156. static::assertJson($expectedJson, $message);
  47157. static::assertJson($actualJson, $message);
  47158. static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
  47159. }
  47160. /**
  47161. * Asserts that two given JSON encoded objects or arrays are not equal.
  47162. *
  47163. * @throws ExpectationFailedException
  47164. */
  47165. final public static function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
  47166. {
  47167. static::assertJson($expectedJson, $message);
  47168. static::assertJson($actualJson, $message);
  47169. static::assertThat($actualJson, new LogicalNot(new JsonMatches($expectedJson)), $message);
  47170. }
  47171. /**
  47172. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  47173. *
  47174. * @throws ExpectationFailedException
  47175. */
  47176. final public static function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
  47177. {
  47178. static::assertFileExists($expectedFile, $message);
  47179. $expectedJson = file_get_contents($expectedFile);
  47180. static::assertJson($expectedJson, $message);
  47181. static::assertJson($actualJson, $message);
  47182. static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
  47183. }
  47184. /**
  47185. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  47186. *
  47187. * @throws ExpectationFailedException
  47188. */
  47189. final public static function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
  47190. {
  47191. static::assertFileExists($expectedFile, $message);
  47192. $expectedJson = file_get_contents($expectedFile);
  47193. static::assertJson($expectedJson, $message);
  47194. static::assertJson($actualJson, $message);
  47195. static::assertThat($actualJson, new LogicalNot(new JsonMatches($expectedJson)), $message);
  47196. }
  47197. /**
  47198. * Asserts that two JSON files are equal.
  47199. *
  47200. * @throws ExpectationFailedException
  47201. */
  47202. final public static function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
  47203. {
  47204. static::assertFileExists($expectedFile, $message);
  47205. static::assertFileExists($actualFile, $message);
  47206. $actualJson = file_get_contents($actualFile);
  47207. $expectedJson = file_get_contents($expectedFile);
  47208. static::assertJson($expectedJson, $message);
  47209. static::assertJson($actualJson, $message);
  47210. $constraintExpected = new JsonMatches($expectedJson);
  47211. $constraintActual = new JsonMatches($actualJson);
  47212. static::assertThat($expectedJson, $constraintActual, $message);
  47213. static::assertThat($actualJson, $constraintExpected, $message);
  47214. }
  47215. /**
  47216. * Asserts that two JSON files are not equal.
  47217. *
  47218. * @throws ExpectationFailedException
  47219. */
  47220. final public static function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
  47221. {
  47222. static::assertFileExists($expectedFile, $message);
  47223. static::assertFileExists($actualFile, $message);
  47224. $actualJson = file_get_contents($actualFile);
  47225. $expectedJson = file_get_contents($expectedFile);
  47226. static::assertJson($expectedJson, $message);
  47227. static::assertJson($actualJson, $message);
  47228. $constraintExpected = new JsonMatches($expectedJson);
  47229. $constraintActual = new JsonMatches($actualJson);
  47230. static::assertThat($expectedJson, new LogicalNot($constraintActual), $message);
  47231. static::assertThat($actualJson, new LogicalNot($constraintExpected), $message);
  47232. }
  47233. /**
  47234. * @throws Exception
  47235. */
  47236. final public static function logicalAnd(mixed ...$constraints): LogicalAnd
  47237. {
  47238. return LogicalAnd::fromConstraints(...$constraints);
  47239. }
  47240. final public static function logicalOr(mixed ...$constraints): LogicalOr
  47241. {
  47242. return LogicalOr::fromConstraints(...$constraints);
  47243. }
  47244. final public static function logicalNot(Constraint $constraint): LogicalNot
  47245. {
  47246. return new LogicalNot($constraint);
  47247. }
  47248. final public static function logicalXor(mixed ...$constraints): LogicalXor
  47249. {
  47250. return LogicalXor::fromConstraints(...$constraints);
  47251. }
  47252. final public static function anything(): IsAnything
  47253. {
  47254. return new IsAnything();
  47255. }
  47256. final public static function isTrue(): IsTrue
  47257. {
  47258. return new IsTrue();
  47259. }
  47260. /**
  47261. * @psalm-template CallbackInput of mixed
  47262. *
  47263. * @psalm-param callable(CallbackInput $callback): bool $callback
  47264. *
  47265. * @psalm-return Callback<CallbackInput>
  47266. */
  47267. final public static function callback(callable $callback): Callback
  47268. {
  47269. return new Callback($callback);
  47270. }
  47271. final public static function isFalse(): IsFalse
  47272. {
  47273. return new IsFalse();
  47274. }
  47275. final public static function isJson(): IsJson
  47276. {
  47277. return new IsJson();
  47278. }
  47279. final public static function isNull(): IsNull
  47280. {
  47281. return new IsNull();
  47282. }
  47283. final public static function isFinite(): IsFinite
  47284. {
  47285. return new IsFinite();
  47286. }
  47287. final public static function isInfinite(): IsInfinite
  47288. {
  47289. return new IsInfinite();
  47290. }
  47291. final public static function isNan(): IsNan
  47292. {
  47293. return new IsNan();
  47294. }
  47295. final public static function containsEqual(mixed $value): TraversableContainsEqual
  47296. {
  47297. return new TraversableContainsEqual($value);
  47298. }
  47299. final public static function containsIdentical(mixed $value): TraversableContainsIdentical
  47300. {
  47301. return new TraversableContainsIdentical($value);
  47302. }
  47303. /**
  47304. * @throws Exception
  47305. */
  47306. final public static function containsOnly(string $type): TraversableContainsOnly
  47307. {
  47308. return new TraversableContainsOnly($type);
  47309. }
  47310. /**
  47311. * @throws Exception
  47312. */
  47313. final public static function containsOnlyInstancesOf(string $className): TraversableContainsOnly
  47314. {
  47315. return new TraversableContainsOnly($className, \false);
  47316. }
  47317. final public static function arrayHasKey(mixed $key): ArrayHasKey
  47318. {
  47319. return new ArrayHasKey($key);
  47320. }
  47321. final public static function isList(): IsList
  47322. {
  47323. return new IsList();
  47324. }
  47325. final public static function equalTo(mixed $value): IsEqual
  47326. {
  47327. return new IsEqual($value, 0.0, \false, \false);
  47328. }
  47329. final public static function equalToCanonicalizing(mixed $value): IsEqualCanonicalizing
  47330. {
  47331. return new IsEqualCanonicalizing($value);
  47332. }
  47333. final public static function equalToIgnoringCase(mixed $value): IsEqualIgnoringCase
  47334. {
  47335. return new IsEqualIgnoringCase($value);
  47336. }
  47337. final public static function equalToWithDelta(mixed $value, float $delta): IsEqualWithDelta
  47338. {
  47339. return new IsEqualWithDelta($value, $delta);
  47340. }
  47341. final public static function isEmpty(): IsEmpty
  47342. {
  47343. return new IsEmpty();
  47344. }
  47345. final public static function isWritable(): IsWritable
  47346. {
  47347. return new IsWritable();
  47348. }
  47349. final public static function isReadable(): IsReadable
  47350. {
  47351. return new IsReadable();
  47352. }
  47353. final public static function directoryExists(): DirectoryExists
  47354. {
  47355. return new DirectoryExists();
  47356. }
  47357. final public static function fileExists(): FileExists
  47358. {
  47359. return new FileExists();
  47360. }
  47361. final public static function greaterThan(mixed $value): GreaterThan
  47362. {
  47363. return new GreaterThan($value);
  47364. }
  47365. final public static function greaterThanOrEqual(mixed $value): LogicalOr
  47366. {
  47367. return static::logicalOr(new IsEqual($value), new GreaterThan($value));
  47368. }
  47369. final public static function identicalTo(mixed $value): IsIdentical
  47370. {
  47371. return new IsIdentical($value);
  47372. }
  47373. /**
  47374. * @throws UnknownClassOrInterfaceException
  47375. */
  47376. final public static function isInstanceOf(string $className): IsInstanceOf
  47377. {
  47378. return new IsInstanceOf($className);
  47379. }
  47380. /**
  47381. * @psalm-param 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' $type
  47382. *
  47383. * @throws Exception
  47384. */
  47385. final public static function isType(string $type): IsType
  47386. {
  47387. return new IsType($type);
  47388. }
  47389. final public static function lessThan(mixed $value): LessThan
  47390. {
  47391. return new LessThan($value);
  47392. }
  47393. final public static function lessThanOrEqual(mixed $value): LogicalOr
  47394. {
  47395. return static::logicalOr(new IsEqual($value), new LessThan($value));
  47396. }
  47397. final public static function matchesRegularExpression(string $pattern): RegularExpression
  47398. {
  47399. return new RegularExpression($pattern);
  47400. }
  47401. final public static function matches(string $string): StringMatchesFormatDescription
  47402. {
  47403. return new StringMatchesFormatDescription($string);
  47404. }
  47405. /**
  47406. * @psalm-param non-empty-string $prefix
  47407. *
  47408. * @throws InvalidArgumentException
  47409. */
  47410. final public static function stringStartsWith(string $prefix): StringStartsWith
  47411. {
  47412. return new StringStartsWith($prefix);
  47413. }
  47414. final public static function stringContains(string $string, bool $case = \true): StringContains
  47415. {
  47416. return new StringContains($string, $case);
  47417. }
  47418. /**
  47419. * @psalm-param non-empty-string $suffix
  47420. *
  47421. * @throws InvalidArgumentException
  47422. */
  47423. final public static function stringEndsWith(string $suffix): StringEndsWith
  47424. {
  47425. return new StringEndsWith($suffix);
  47426. }
  47427. final public static function stringEqualsStringIgnoringLineEndings(string $string): StringEqualsStringIgnoringLineEndings
  47428. {
  47429. return new StringEqualsStringIgnoringLineEndings($string);
  47430. }
  47431. final public static function countOf(int $count): Count
  47432. {
  47433. return new Count($count);
  47434. }
  47435. final public static function objectEquals(object $object, string $method = 'equals'): ObjectEquals
  47436. {
  47437. return new ObjectEquals($object, $method);
  47438. }
  47439. /**
  47440. * Fails a test with the given message.
  47441. *
  47442. * @throws AssertionFailedError
  47443. */
  47444. final public static function fail(string $message = ''): never
  47445. {
  47446. self::$count++;
  47447. throw new \PHPUnit\Framework\AssertionFailedError($message);
  47448. }
  47449. /**
  47450. * Mark the test as incomplete.
  47451. *
  47452. * @throws IncompleteTestError
  47453. */
  47454. final public static function markTestIncomplete(string $message = ''): never
  47455. {
  47456. throw new \PHPUnit\Framework\IncompleteTestError($message);
  47457. }
  47458. /**
  47459. * Mark the test as skipped.
  47460. *
  47461. * @throws SkippedWithMessageException
  47462. */
  47463. final public static function markTestSkipped(string $message = ''): never
  47464. {
  47465. throw new \PHPUnit\Framework\SkippedWithMessageException($message);
  47466. }
  47467. /**
  47468. * Return the current assertion count.
  47469. */
  47470. final public static function getCount(): int
  47471. {
  47472. return self::$count;
  47473. }
  47474. /**
  47475. * Reset the assertion counter.
  47476. */
  47477. final public static function resetCount(): void
  47478. {
  47479. self::$count = 0;
  47480. }
  47481. private static function isNativeType(string $type): bool
  47482. {
  47483. return match ($type) {
  47484. 'numeric', 'integer', 'int', 'iterable', 'float', 'string', 'boolean', 'bool', 'null', 'array', 'object', 'resource', 'scalar' => \true,
  47485. default => \false,
  47486. };
  47487. }
  47488. }
  47489. <?php
  47490. declare (strict_types=1);
  47491. /*
  47492. * This file is part of PHPUnit.
  47493. *
  47494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  47495. *
  47496. * For the full copyright and license information, please view the LICENSE
  47497. * file that was distributed with this source code.
  47498. */
  47499. namespace PHPUnit\Framework;
  47500. use function func_get_args;
  47501. use function function_exists;
  47502. use ArrayAccess;
  47503. use Countable;
  47504. use PHPUnit\Framework\Constraint\ArrayHasKey;
  47505. use PHPUnit\Framework\Constraint\Callback;
  47506. use PHPUnit\Framework\Constraint\Constraint;
  47507. use PHPUnit\Framework\Constraint\Count;
  47508. use PHPUnit\Framework\Constraint\DirectoryExists;
  47509. use PHPUnit\Framework\Constraint\FileExists;
  47510. use PHPUnit\Framework\Constraint\GreaterThan;
  47511. use PHPUnit\Framework\Constraint\IsAnything;
  47512. use PHPUnit\Framework\Constraint\IsEmpty;
  47513. use PHPUnit\Framework\Constraint\IsEqual;
  47514. use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
  47515. use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
  47516. use PHPUnit\Framework\Constraint\IsEqualWithDelta;
  47517. use PHPUnit\Framework\Constraint\IsFalse;
  47518. use PHPUnit\Framework\Constraint\IsFinite;
  47519. use PHPUnit\Framework\Constraint\IsIdentical;
  47520. use PHPUnit\Framework\Constraint\IsInfinite;
  47521. use PHPUnit\Framework\Constraint\IsInstanceOf;
  47522. use PHPUnit\Framework\Constraint\IsJson;
  47523. use PHPUnit\Framework\Constraint\IsList;
  47524. use PHPUnit\Framework\Constraint\IsNan;
  47525. use PHPUnit\Framework\Constraint\IsNull;
  47526. use PHPUnit\Framework\Constraint\IsReadable;
  47527. use PHPUnit\Framework\Constraint\IsTrue;
  47528. use PHPUnit\Framework\Constraint\IsType;
  47529. use PHPUnit\Framework\Constraint\IsWritable;
  47530. use PHPUnit\Framework\Constraint\LessThan;
  47531. use PHPUnit\Framework\Constraint\LogicalAnd;
  47532. use PHPUnit\Framework\Constraint\LogicalNot;
  47533. use PHPUnit\Framework\Constraint\LogicalOr;
  47534. use PHPUnit\Framework\Constraint\LogicalXor;
  47535. use PHPUnit\Framework\Constraint\ObjectEquals;
  47536. use PHPUnit\Framework\Constraint\RegularExpression;
  47537. use PHPUnit\Framework\Constraint\StringContains;
  47538. use PHPUnit\Framework\Constraint\StringEndsWith;
  47539. use PHPUnit\Framework\Constraint\StringEqualsStringIgnoringLineEndings;
  47540. use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
  47541. use PHPUnit\Framework\Constraint\StringStartsWith;
  47542. use PHPUnit\Framework\Constraint\TraversableContainsEqual;
  47543. use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
  47544. use PHPUnit\Framework\Constraint\TraversableContainsOnly;
  47545. use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
  47546. use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
  47547. use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
  47548. use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
  47549. use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
  47550. use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
  47551. use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
  47552. use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
  47553. use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
  47554. use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
  47555. use PHPUnit\Framework\MockObject\Stub\ReturnStub;
  47556. use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
  47557. use PHPUnit\Util\Xml\XmlException;
  47558. use Throwable;
  47559. if (!function_exists('PHPUnit\Framework\assertArrayHasKey')) {
  47560. /**
  47561. * Asserts that an array has a specified key.
  47562. *
  47563. * @throws Exception
  47564. * @throws ExpectationFailedException
  47565. *
  47566. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47567. *
  47568. * @see Assert::assertArrayHasKey
  47569. */
  47570. function assertArrayHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
  47571. {
  47572. \PHPUnit\Framework\Assert::assertArrayHasKey(...func_get_args());
  47573. }
  47574. }
  47575. if (!function_exists('PHPUnit\Framework\assertArrayNotHasKey')) {
  47576. /**
  47577. * Asserts that an array does not have a specified key.
  47578. *
  47579. * @throws Exception
  47580. * @throws ExpectationFailedException
  47581. *
  47582. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47583. *
  47584. * @see Assert::assertArrayNotHasKey
  47585. */
  47586. function assertArrayNotHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
  47587. {
  47588. \PHPUnit\Framework\Assert::assertArrayNotHasKey(...func_get_args());
  47589. }
  47590. }
  47591. if (!function_exists('PHPUnit\Framework\assertIsList')) {
  47592. /**
  47593. * @throws ExpectationFailedException
  47594. *
  47595. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47596. *
  47597. * @see Assert::assertIsList
  47598. */
  47599. function assertIsList(mixed $array, string $message = ''): void
  47600. {
  47601. \PHPUnit\Framework\Assert::assertIsList(...func_get_args());
  47602. }
  47603. }
  47604. if (!function_exists('PHPUnit\Framework\assertContains')) {
  47605. /**
  47606. * Asserts that a haystack contains a needle.
  47607. *
  47608. * @throws Exception
  47609. * @throws ExpectationFailedException
  47610. *
  47611. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47612. *
  47613. * @see Assert::assertContains
  47614. */
  47615. function assertContains(mixed $needle, iterable $haystack, string $message = ''): void
  47616. {
  47617. \PHPUnit\Framework\Assert::assertContains(...func_get_args());
  47618. }
  47619. }
  47620. if (!function_exists('PHPUnit\Framework\assertContainsEquals')) {
  47621. /**
  47622. * @throws ExpectationFailedException
  47623. *
  47624. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47625. *
  47626. * @see Assert::assertContainsEquals
  47627. */
  47628. function assertContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
  47629. {
  47630. \PHPUnit\Framework\Assert::assertContainsEquals(...func_get_args());
  47631. }
  47632. }
  47633. if (!function_exists('PHPUnit\Framework\assertNotContains')) {
  47634. /**
  47635. * Asserts that a haystack does not contain a needle.
  47636. *
  47637. * @throws Exception
  47638. * @throws ExpectationFailedException
  47639. *
  47640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47641. *
  47642. * @see Assert::assertNotContains
  47643. */
  47644. function assertNotContains(mixed $needle, iterable $haystack, string $message = ''): void
  47645. {
  47646. \PHPUnit\Framework\Assert::assertNotContains(...func_get_args());
  47647. }
  47648. }
  47649. if (!function_exists('PHPUnit\Framework\assertNotContainsEquals')) {
  47650. /**
  47651. * @throws ExpectationFailedException
  47652. *
  47653. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47654. *
  47655. * @see Assert::assertNotContainsEquals
  47656. */
  47657. function assertNotContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
  47658. {
  47659. \PHPUnit\Framework\Assert::assertNotContainsEquals(...func_get_args());
  47660. }
  47661. }
  47662. if (!function_exists('PHPUnit\Framework\assertContainsOnly')) {
  47663. /**
  47664. * Asserts that a haystack contains only values of a given type.
  47665. *
  47666. * @throws Exception
  47667. * @throws ExpectationFailedException
  47668. *
  47669. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47670. *
  47671. * @see Assert::assertContainsOnly
  47672. */
  47673. function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
  47674. {
  47675. \PHPUnit\Framework\Assert::assertContainsOnly(...func_get_args());
  47676. }
  47677. }
  47678. if (!function_exists('PHPUnit\Framework\assertContainsOnlyInstancesOf')) {
  47679. /**
  47680. * Asserts that a haystack contains only instances of a given class name.
  47681. *
  47682. * @throws Exception
  47683. * @throws ExpectationFailedException
  47684. *
  47685. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47686. *
  47687. * @see Assert::assertContainsOnlyInstancesOf
  47688. */
  47689. function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
  47690. {
  47691. \PHPUnit\Framework\Assert::assertContainsOnlyInstancesOf(...func_get_args());
  47692. }
  47693. }
  47694. if (!function_exists('PHPUnit\Framework\assertNotContainsOnly')) {
  47695. /**
  47696. * Asserts that a haystack does not contain only values of a given type.
  47697. *
  47698. * @throws Exception
  47699. * @throws ExpectationFailedException
  47700. *
  47701. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47702. *
  47703. * @see Assert::assertNotContainsOnly
  47704. */
  47705. function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
  47706. {
  47707. \PHPUnit\Framework\Assert::assertNotContainsOnly(...func_get_args());
  47708. }
  47709. }
  47710. if (!function_exists('PHPUnit\Framework\assertCount')) {
  47711. /**
  47712. * Asserts the number of elements of an array, Countable or Traversable.
  47713. *
  47714. * @throws Exception
  47715. * @throws ExpectationFailedException
  47716. * @throws GeneratorNotSupportedException
  47717. *
  47718. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47719. *
  47720. * @see Assert::assertCount
  47721. */
  47722. function assertCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
  47723. {
  47724. \PHPUnit\Framework\Assert::assertCount(...func_get_args());
  47725. }
  47726. }
  47727. if (!function_exists('PHPUnit\Framework\assertNotCount')) {
  47728. /**
  47729. * Asserts the number of elements of an array, Countable or Traversable.
  47730. *
  47731. * @throws Exception
  47732. * @throws ExpectationFailedException
  47733. * @throws GeneratorNotSupportedException
  47734. *
  47735. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47736. *
  47737. * @see Assert::assertNotCount
  47738. */
  47739. function assertNotCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
  47740. {
  47741. \PHPUnit\Framework\Assert::assertNotCount(...func_get_args());
  47742. }
  47743. }
  47744. if (!function_exists('PHPUnit\Framework\assertEquals')) {
  47745. /**
  47746. * Asserts that two variables are equal.
  47747. *
  47748. * @throws ExpectationFailedException
  47749. *
  47750. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47751. *
  47752. * @see Assert::assertEquals
  47753. */
  47754. function assertEquals(mixed $expected, mixed $actual, string $message = ''): void
  47755. {
  47756. \PHPUnit\Framework\Assert::assertEquals(...func_get_args());
  47757. }
  47758. }
  47759. if (!function_exists('PHPUnit\Framework\assertEqualsCanonicalizing')) {
  47760. /**
  47761. * Asserts that two variables are equal (canonicalizing).
  47762. *
  47763. * @throws ExpectationFailedException
  47764. *
  47765. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47766. *
  47767. * @see Assert::assertEqualsCanonicalizing
  47768. */
  47769. function assertEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
  47770. {
  47771. \PHPUnit\Framework\Assert::assertEqualsCanonicalizing(...func_get_args());
  47772. }
  47773. }
  47774. if (!function_exists('PHPUnit\Framework\assertEqualsIgnoringCase')) {
  47775. /**
  47776. * Asserts that two variables are equal (ignoring case).
  47777. *
  47778. * @throws ExpectationFailedException
  47779. *
  47780. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47781. *
  47782. * @see Assert::assertEqualsIgnoringCase
  47783. */
  47784. function assertEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
  47785. {
  47786. \PHPUnit\Framework\Assert::assertEqualsIgnoringCase(...func_get_args());
  47787. }
  47788. }
  47789. if (!function_exists('PHPUnit\Framework\assertEqualsWithDelta')) {
  47790. /**
  47791. * Asserts that two variables are equal (with delta).
  47792. *
  47793. * @throws ExpectationFailedException
  47794. *
  47795. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47796. *
  47797. * @see Assert::assertEqualsWithDelta
  47798. */
  47799. function assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
  47800. {
  47801. \PHPUnit\Framework\Assert::assertEqualsWithDelta(...func_get_args());
  47802. }
  47803. }
  47804. if (!function_exists('PHPUnit\Framework\assertNotEquals')) {
  47805. /**
  47806. * Asserts that two variables are not equal.
  47807. *
  47808. * @throws ExpectationFailedException
  47809. *
  47810. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47811. *
  47812. * @see Assert::assertNotEquals
  47813. */
  47814. function assertNotEquals(mixed $expected, mixed $actual, string $message = ''): void
  47815. {
  47816. \PHPUnit\Framework\Assert::assertNotEquals(...func_get_args());
  47817. }
  47818. }
  47819. if (!function_exists('PHPUnit\Framework\assertNotEqualsCanonicalizing')) {
  47820. /**
  47821. * Asserts that two variables are not equal (canonicalizing).
  47822. *
  47823. * @throws ExpectationFailedException
  47824. *
  47825. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47826. *
  47827. * @see Assert::assertNotEqualsCanonicalizing
  47828. */
  47829. function assertNotEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
  47830. {
  47831. \PHPUnit\Framework\Assert::assertNotEqualsCanonicalizing(...func_get_args());
  47832. }
  47833. }
  47834. if (!function_exists('PHPUnit\Framework\assertNotEqualsIgnoringCase')) {
  47835. /**
  47836. * Asserts that two variables are not equal (ignoring case).
  47837. *
  47838. * @throws ExpectationFailedException
  47839. *
  47840. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47841. *
  47842. * @see Assert::assertNotEqualsIgnoringCase
  47843. */
  47844. function assertNotEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
  47845. {
  47846. \PHPUnit\Framework\Assert::assertNotEqualsIgnoringCase(...func_get_args());
  47847. }
  47848. }
  47849. if (!function_exists('PHPUnit\Framework\assertNotEqualsWithDelta')) {
  47850. /**
  47851. * Asserts that two variables are not equal (with delta).
  47852. *
  47853. * @throws ExpectationFailedException
  47854. *
  47855. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47856. *
  47857. * @see Assert::assertNotEqualsWithDelta
  47858. */
  47859. function assertNotEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
  47860. {
  47861. \PHPUnit\Framework\Assert::assertNotEqualsWithDelta(...func_get_args());
  47862. }
  47863. }
  47864. if (!function_exists('PHPUnit\Framework\assertObjectEquals')) {
  47865. /**
  47866. * @throws ExpectationFailedException
  47867. *
  47868. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47869. *
  47870. * @see Assert::assertObjectEquals
  47871. */
  47872. function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
  47873. {
  47874. \PHPUnit\Framework\Assert::assertObjectEquals(...func_get_args());
  47875. }
  47876. }
  47877. if (!function_exists('PHPUnit\Framework\assertEmpty')) {
  47878. /**
  47879. * Asserts that a variable is empty.
  47880. *
  47881. * @throws ExpectationFailedException
  47882. * @throws GeneratorNotSupportedException
  47883. *
  47884. * @psalm-assert empty $actual
  47885. *
  47886. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47887. *
  47888. * @see Assert::assertEmpty
  47889. */
  47890. function assertEmpty(mixed $actual, string $message = ''): void
  47891. {
  47892. \PHPUnit\Framework\Assert::assertEmpty(...func_get_args());
  47893. }
  47894. }
  47895. if (!function_exists('PHPUnit\Framework\assertNotEmpty')) {
  47896. /**
  47897. * Asserts that a variable is not empty.
  47898. *
  47899. * @throws ExpectationFailedException
  47900. * @throws GeneratorNotSupportedException
  47901. *
  47902. * @psalm-assert !empty $actual
  47903. *
  47904. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47905. *
  47906. * @see Assert::assertNotEmpty
  47907. */
  47908. function assertNotEmpty(mixed $actual, string $message = ''): void
  47909. {
  47910. \PHPUnit\Framework\Assert::assertNotEmpty(...func_get_args());
  47911. }
  47912. }
  47913. if (!function_exists('PHPUnit\Framework\assertGreaterThan')) {
  47914. /**
  47915. * Asserts that a value is greater than another value.
  47916. *
  47917. * @throws ExpectationFailedException
  47918. *
  47919. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47920. *
  47921. * @see Assert::assertGreaterThan
  47922. */
  47923. function assertGreaterThan(mixed $expected, mixed $actual, string $message = ''): void
  47924. {
  47925. \PHPUnit\Framework\Assert::assertGreaterThan(...func_get_args());
  47926. }
  47927. }
  47928. if (!function_exists('PHPUnit\Framework\assertGreaterThanOrEqual')) {
  47929. /**
  47930. * Asserts that a value is greater than or equal to another value.
  47931. *
  47932. * @throws ExpectationFailedException
  47933. *
  47934. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47935. *
  47936. * @see Assert::assertGreaterThanOrEqual
  47937. */
  47938. function assertGreaterThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
  47939. {
  47940. \PHPUnit\Framework\Assert::assertGreaterThanOrEqual(...func_get_args());
  47941. }
  47942. }
  47943. if (!function_exists('PHPUnit\Framework\assertLessThan')) {
  47944. /**
  47945. * Asserts that a value is smaller than another value.
  47946. *
  47947. * @throws ExpectationFailedException
  47948. *
  47949. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47950. *
  47951. * @see Assert::assertLessThan
  47952. */
  47953. function assertLessThan(mixed $expected, mixed $actual, string $message = ''): void
  47954. {
  47955. \PHPUnit\Framework\Assert::assertLessThan(...func_get_args());
  47956. }
  47957. }
  47958. if (!function_exists('PHPUnit\Framework\assertLessThanOrEqual')) {
  47959. /**
  47960. * Asserts that a value is smaller than or equal to another value.
  47961. *
  47962. * @throws ExpectationFailedException
  47963. *
  47964. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47965. *
  47966. * @see Assert::assertLessThanOrEqual
  47967. */
  47968. function assertLessThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
  47969. {
  47970. \PHPUnit\Framework\Assert::assertLessThanOrEqual(...func_get_args());
  47971. }
  47972. }
  47973. if (!function_exists('PHPUnit\Framework\assertFileEquals')) {
  47974. /**
  47975. * Asserts that the contents of one file is equal to the contents of another
  47976. * file.
  47977. *
  47978. * @throws ExpectationFailedException
  47979. *
  47980. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47981. *
  47982. * @see Assert::assertFileEquals
  47983. */
  47984. function assertFileEquals(string $expected, string $actual, string $message = ''): void
  47985. {
  47986. \PHPUnit\Framework\Assert::assertFileEquals(...func_get_args());
  47987. }
  47988. }
  47989. if (!function_exists('PHPUnit\Framework\assertFileEqualsCanonicalizing')) {
  47990. /**
  47991. * Asserts that the contents of one file is equal to the contents of another
  47992. * file (canonicalizing).
  47993. *
  47994. * @throws ExpectationFailedException
  47995. *
  47996. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  47997. *
  47998. * @see Assert::assertFileEqualsCanonicalizing
  47999. */
  48000. function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
  48001. {
  48002. \PHPUnit\Framework\Assert::assertFileEqualsCanonicalizing(...func_get_args());
  48003. }
  48004. }
  48005. if (!function_exists('PHPUnit\Framework\assertFileEqualsIgnoringCase')) {
  48006. /**
  48007. * Asserts that the contents of one file is equal to the contents of another
  48008. * file (ignoring case).
  48009. *
  48010. * @throws ExpectationFailedException
  48011. *
  48012. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48013. *
  48014. * @see Assert::assertFileEqualsIgnoringCase
  48015. */
  48016. function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
  48017. {
  48018. \PHPUnit\Framework\Assert::assertFileEqualsIgnoringCase(...func_get_args());
  48019. }
  48020. }
  48021. if (!function_exists('PHPUnit\Framework\assertFileNotEquals')) {
  48022. /**
  48023. * Asserts that the contents of one file is not equal to the contents of
  48024. * another file.
  48025. *
  48026. * @throws ExpectationFailedException
  48027. *
  48028. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48029. *
  48030. * @see Assert::assertFileNotEquals
  48031. */
  48032. function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
  48033. {
  48034. \PHPUnit\Framework\Assert::assertFileNotEquals(...func_get_args());
  48035. }
  48036. }
  48037. if (!function_exists('PHPUnit\Framework\assertFileNotEqualsCanonicalizing')) {
  48038. /**
  48039. * Asserts that the contents of one file is not equal to the contents of another
  48040. * file (canonicalizing).
  48041. *
  48042. * @throws ExpectationFailedException
  48043. *
  48044. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48045. *
  48046. * @see Assert::assertFileNotEqualsCanonicalizing
  48047. */
  48048. function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
  48049. {
  48050. \PHPUnit\Framework\Assert::assertFileNotEqualsCanonicalizing(...func_get_args());
  48051. }
  48052. }
  48053. if (!function_exists('PHPUnit\Framework\assertFileNotEqualsIgnoringCase')) {
  48054. /**
  48055. * Asserts that the contents of one file is not equal to the contents of another
  48056. * file (ignoring case).
  48057. *
  48058. * @throws ExpectationFailedException
  48059. *
  48060. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48061. *
  48062. * @see Assert::assertFileNotEqualsIgnoringCase
  48063. */
  48064. function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
  48065. {
  48066. \PHPUnit\Framework\Assert::assertFileNotEqualsIgnoringCase(...func_get_args());
  48067. }
  48068. }
  48069. if (!function_exists('PHPUnit\Framework\assertStringEqualsFile')) {
  48070. /**
  48071. * Asserts that the contents of a string is equal
  48072. * to the contents of a file.
  48073. *
  48074. * @throws ExpectationFailedException
  48075. *
  48076. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48077. *
  48078. * @see Assert::assertStringEqualsFile
  48079. */
  48080. function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
  48081. {
  48082. \PHPUnit\Framework\Assert::assertStringEqualsFile(...func_get_args());
  48083. }
  48084. }
  48085. if (!function_exists('PHPUnit\Framework\assertStringEqualsFileCanonicalizing')) {
  48086. /**
  48087. * Asserts that the contents of a string is equal
  48088. * to the contents of a file (canonicalizing).
  48089. *
  48090. * @throws ExpectationFailedException
  48091. *
  48092. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48093. *
  48094. * @see Assert::assertStringEqualsFileCanonicalizing
  48095. */
  48096. function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
  48097. {
  48098. \PHPUnit\Framework\Assert::assertStringEqualsFileCanonicalizing(...func_get_args());
  48099. }
  48100. }
  48101. if (!function_exists('PHPUnit\Framework\assertStringEqualsFileIgnoringCase')) {
  48102. /**
  48103. * Asserts that the contents of a string is equal
  48104. * to the contents of a file (ignoring case).
  48105. *
  48106. * @throws ExpectationFailedException
  48107. *
  48108. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48109. *
  48110. * @see Assert::assertStringEqualsFileIgnoringCase
  48111. */
  48112. function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
  48113. {
  48114. \PHPUnit\Framework\Assert::assertStringEqualsFileIgnoringCase(...func_get_args());
  48115. }
  48116. }
  48117. if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFile')) {
  48118. /**
  48119. * Asserts that the contents of a string is not equal
  48120. * to the contents of a file.
  48121. *
  48122. * @throws ExpectationFailedException
  48123. *
  48124. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48125. *
  48126. * @see Assert::assertStringNotEqualsFile
  48127. */
  48128. function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
  48129. {
  48130. \PHPUnit\Framework\Assert::assertStringNotEqualsFile(...func_get_args());
  48131. }
  48132. }
  48133. if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileCanonicalizing')) {
  48134. /**
  48135. * Asserts that the contents of a string is not equal
  48136. * to the contents of a file (canonicalizing).
  48137. *
  48138. * @throws ExpectationFailedException
  48139. *
  48140. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48141. *
  48142. * @see Assert::assertStringNotEqualsFileCanonicalizing
  48143. */
  48144. function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
  48145. {
  48146. \PHPUnit\Framework\Assert::assertStringNotEqualsFileCanonicalizing(...func_get_args());
  48147. }
  48148. }
  48149. if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileIgnoringCase')) {
  48150. /**
  48151. * Asserts that the contents of a string is not equal
  48152. * to the contents of a file (ignoring case).
  48153. *
  48154. * @throws ExpectationFailedException
  48155. *
  48156. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48157. *
  48158. * @see Assert::assertStringNotEqualsFileIgnoringCase
  48159. */
  48160. function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
  48161. {
  48162. \PHPUnit\Framework\Assert::assertStringNotEqualsFileIgnoringCase(...func_get_args());
  48163. }
  48164. }
  48165. if (!function_exists('PHPUnit\Framework\assertIsReadable')) {
  48166. /**
  48167. * Asserts that a file/dir is readable.
  48168. *
  48169. * @throws ExpectationFailedException
  48170. *
  48171. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48172. *
  48173. * @see Assert::assertIsReadable
  48174. */
  48175. function assertIsReadable(string $filename, string $message = ''): void
  48176. {
  48177. \PHPUnit\Framework\Assert::assertIsReadable(...func_get_args());
  48178. }
  48179. }
  48180. if (!function_exists('PHPUnit\Framework\assertIsNotReadable')) {
  48181. /**
  48182. * Asserts that a file/dir exists and is not readable.
  48183. *
  48184. * @throws ExpectationFailedException
  48185. *
  48186. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48187. *
  48188. * @see Assert::assertIsNotReadable
  48189. */
  48190. function assertIsNotReadable(string $filename, string $message = ''): void
  48191. {
  48192. \PHPUnit\Framework\Assert::assertIsNotReadable(...func_get_args());
  48193. }
  48194. }
  48195. if (!function_exists('PHPUnit\Framework\assertIsWritable')) {
  48196. /**
  48197. * Asserts that a file/dir exists and is writable.
  48198. *
  48199. * @throws ExpectationFailedException
  48200. *
  48201. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48202. *
  48203. * @see Assert::assertIsWritable
  48204. */
  48205. function assertIsWritable(string $filename, string $message = ''): void
  48206. {
  48207. \PHPUnit\Framework\Assert::assertIsWritable(...func_get_args());
  48208. }
  48209. }
  48210. if (!function_exists('PHPUnit\Framework\assertIsNotWritable')) {
  48211. /**
  48212. * Asserts that a file/dir exists and is not writable.
  48213. *
  48214. * @throws ExpectationFailedException
  48215. *
  48216. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48217. *
  48218. * @see Assert::assertIsNotWritable
  48219. */
  48220. function assertIsNotWritable(string $filename, string $message = ''): void
  48221. {
  48222. \PHPUnit\Framework\Assert::assertIsNotWritable(...func_get_args());
  48223. }
  48224. }
  48225. if (!function_exists('PHPUnit\Framework\assertDirectoryExists')) {
  48226. /**
  48227. * Asserts that a directory exists.
  48228. *
  48229. * @throws ExpectationFailedException
  48230. *
  48231. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48232. *
  48233. * @see Assert::assertDirectoryExists
  48234. */
  48235. function assertDirectoryExists(string $directory, string $message = ''): void
  48236. {
  48237. \PHPUnit\Framework\Assert::assertDirectoryExists(...func_get_args());
  48238. }
  48239. }
  48240. if (!function_exists('PHPUnit\Framework\assertDirectoryDoesNotExist')) {
  48241. /**
  48242. * Asserts that a directory does not exist.
  48243. *
  48244. * @throws ExpectationFailedException
  48245. *
  48246. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48247. *
  48248. * @see Assert::assertDirectoryDoesNotExist
  48249. */
  48250. function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
  48251. {
  48252. \PHPUnit\Framework\Assert::assertDirectoryDoesNotExist(...func_get_args());
  48253. }
  48254. }
  48255. if (!function_exists('PHPUnit\Framework\assertDirectoryIsReadable')) {
  48256. /**
  48257. * Asserts that a directory exists and is readable.
  48258. *
  48259. * @throws ExpectationFailedException
  48260. *
  48261. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48262. *
  48263. * @see Assert::assertDirectoryIsReadable
  48264. */
  48265. function assertDirectoryIsReadable(string $directory, string $message = ''): void
  48266. {
  48267. \PHPUnit\Framework\Assert::assertDirectoryIsReadable(...func_get_args());
  48268. }
  48269. }
  48270. if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotReadable')) {
  48271. /**
  48272. * Asserts that a directory exists and is not readable.
  48273. *
  48274. * @throws ExpectationFailedException
  48275. *
  48276. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48277. *
  48278. * @see Assert::assertDirectoryIsNotReadable
  48279. */
  48280. function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
  48281. {
  48282. \PHPUnit\Framework\Assert::assertDirectoryIsNotReadable(...func_get_args());
  48283. }
  48284. }
  48285. if (!function_exists('PHPUnit\Framework\assertDirectoryIsWritable')) {
  48286. /**
  48287. * Asserts that a directory exists and is writable.
  48288. *
  48289. * @throws ExpectationFailedException
  48290. *
  48291. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48292. *
  48293. * @see Assert::assertDirectoryIsWritable
  48294. */
  48295. function assertDirectoryIsWritable(string $directory, string $message = ''): void
  48296. {
  48297. \PHPUnit\Framework\Assert::assertDirectoryIsWritable(...func_get_args());
  48298. }
  48299. }
  48300. if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotWritable')) {
  48301. /**
  48302. * Asserts that a directory exists and is not writable.
  48303. *
  48304. * @throws ExpectationFailedException
  48305. *
  48306. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48307. *
  48308. * @see Assert::assertDirectoryIsNotWritable
  48309. */
  48310. function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
  48311. {
  48312. \PHPUnit\Framework\Assert::assertDirectoryIsNotWritable(...func_get_args());
  48313. }
  48314. }
  48315. if (!function_exists('PHPUnit\Framework\assertFileExists')) {
  48316. /**
  48317. * Asserts that a file exists.
  48318. *
  48319. * @throws ExpectationFailedException
  48320. *
  48321. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48322. *
  48323. * @see Assert::assertFileExists
  48324. */
  48325. function assertFileExists(string $filename, string $message = ''): void
  48326. {
  48327. \PHPUnit\Framework\Assert::assertFileExists(...func_get_args());
  48328. }
  48329. }
  48330. if (!function_exists('PHPUnit\Framework\assertFileDoesNotExist')) {
  48331. /**
  48332. * Asserts that a file does not exist.
  48333. *
  48334. * @throws ExpectationFailedException
  48335. *
  48336. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48337. *
  48338. * @see Assert::assertFileDoesNotExist
  48339. */
  48340. function assertFileDoesNotExist(string $filename, string $message = ''): void
  48341. {
  48342. \PHPUnit\Framework\Assert::assertFileDoesNotExist(...func_get_args());
  48343. }
  48344. }
  48345. if (!function_exists('PHPUnit\Framework\assertFileIsReadable')) {
  48346. /**
  48347. * Asserts that a file exists and is readable.
  48348. *
  48349. * @throws ExpectationFailedException
  48350. *
  48351. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48352. *
  48353. * @see Assert::assertFileIsReadable
  48354. */
  48355. function assertFileIsReadable(string $file, string $message = ''): void
  48356. {
  48357. \PHPUnit\Framework\Assert::assertFileIsReadable(...func_get_args());
  48358. }
  48359. }
  48360. if (!function_exists('PHPUnit\Framework\assertFileIsNotReadable')) {
  48361. /**
  48362. * Asserts that a file exists and is not readable.
  48363. *
  48364. * @throws ExpectationFailedException
  48365. *
  48366. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48367. *
  48368. * @see Assert::assertFileIsNotReadable
  48369. */
  48370. function assertFileIsNotReadable(string $file, string $message = ''): void
  48371. {
  48372. \PHPUnit\Framework\Assert::assertFileIsNotReadable(...func_get_args());
  48373. }
  48374. }
  48375. if (!function_exists('PHPUnit\Framework\assertFileIsWritable')) {
  48376. /**
  48377. * Asserts that a file exists and is writable.
  48378. *
  48379. * @throws ExpectationFailedException
  48380. *
  48381. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48382. *
  48383. * @see Assert::assertFileIsWritable
  48384. */
  48385. function assertFileIsWritable(string $file, string $message = ''): void
  48386. {
  48387. \PHPUnit\Framework\Assert::assertFileIsWritable(...func_get_args());
  48388. }
  48389. }
  48390. if (!function_exists('PHPUnit\Framework\assertFileIsNotWritable')) {
  48391. /**
  48392. * Asserts that a file exists and is not writable.
  48393. *
  48394. * @throws ExpectationFailedException
  48395. *
  48396. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48397. *
  48398. * @see Assert::assertFileIsNotWritable
  48399. */
  48400. function assertFileIsNotWritable(string $file, string $message = ''): void
  48401. {
  48402. \PHPUnit\Framework\Assert::assertFileIsNotWritable(...func_get_args());
  48403. }
  48404. }
  48405. if (!function_exists('PHPUnit\Framework\assertTrue')) {
  48406. /**
  48407. * Asserts that a condition is true.
  48408. *
  48409. * @throws ExpectationFailedException
  48410. *
  48411. * @psalm-assert true $condition
  48412. *
  48413. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48414. *
  48415. * @see Assert::assertTrue
  48416. */
  48417. function assertTrue(mixed $condition, string $message = ''): void
  48418. {
  48419. \PHPUnit\Framework\Assert::assertTrue(...func_get_args());
  48420. }
  48421. }
  48422. if (!function_exists('PHPUnit\Framework\assertNotTrue')) {
  48423. /**
  48424. * Asserts that a condition is not true.
  48425. *
  48426. * @throws ExpectationFailedException
  48427. *
  48428. * @psalm-assert !true $condition
  48429. *
  48430. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48431. *
  48432. * @see Assert::assertNotTrue
  48433. */
  48434. function assertNotTrue(mixed $condition, string $message = ''): void
  48435. {
  48436. \PHPUnit\Framework\Assert::assertNotTrue(...func_get_args());
  48437. }
  48438. }
  48439. if (!function_exists('PHPUnit\Framework\assertFalse')) {
  48440. /**
  48441. * Asserts that a condition is false.
  48442. *
  48443. * @throws ExpectationFailedException
  48444. *
  48445. * @psalm-assert false $condition
  48446. *
  48447. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48448. *
  48449. * @see Assert::assertFalse
  48450. */
  48451. function assertFalse(mixed $condition, string $message = ''): void
  48452. {
  48453. \PHPUnit\Framework\Assert::assertFalse(...func_get_args());
  48454. }
  48455. }
  48456. if (!function_exists('PHPUnit\Framework\assertNotFalse')) {
  48457. /**
  48458. * Asserts that a condition is not false.
  48459. *
  48460. * @throws ExpectationFailedException
  48461. *
  48462. * @psalm-assert !false $condition
  48463. *
  48464. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48465. *
  48466. * @see Assert::assertNotFalse
  48467. */
  48468. function assertNotFalse(mixed $condition, string $message = ''): void
  48469. {
  48470. \PHPUnit\Framework\Assert::assertNotFalse(...func_get_args());
  48471. }
  48472. }
  48473. if (!function_exists('PHPUnit\Framework\assertNull')) {
  48474. /**
  48475. * Asserts that a variable is null.
  48476. *
  48477. * @throws ExpectationFailedException
  48478. *
  48479. * @psalm-assert null $actual
  48480. *
  48481. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48482. *
  48483. * @see Assert::assertNull
  48484. */
  48485. function assertNull(mixed $actual, string $message = ''): void
  48486. {
  48487. \PHPUnit\Framework\Assert::assertNull(...func_get_args());
  48488. }
  48489. }
  48490. if (!function_exists('PHPUnit\Framework\assertNotNull')) {
  48491. /**
  48492. * Asserts that a variable is not null.
  48493. *
  48494. * @throws ExpectationFailedException
  48495. *
  48496. * @psalm-assert !null $actual
  48497. *
  48498. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48499. *
  48500. * @see Assert::assertNotNull
  48501. */
  48502. function assertNotNull(mixed $actual, string $message = ''): void
  48503. {
  48504. \PHPUnit\Framework\Assert::assertNotNull(...func_get_args());
  48505. }
  48506. }
  48507. if (!function_exists('PHPUnit\Framework\assertFinite')) {
  48508. /**
  48509. * Asserts that a variable is finite.
  48510. *
  48511. * @throws ExpectationFailedException
  48512. *
  48513. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48514. *
  48515. * @see Assert::assertFinite
  48516. */
  48517. function assertFinite(mixed $actual, string $message = ''): void
  48518. {
  48519. \PHPUnit\Framework\Assert::assertFinite(...func_get_args());
  48520. }
  48521. }
  48522. if (!function_exists('PHPUnit\Framework\assertInfinite')) {
  48523. /**
  48524. * Asserts that a variable is infinite.
  48525. *
  48526. * @throws ExpectationFailedException
  48527. *
  48528. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48529. *
  48530. * @see Assert::assertInfinite
  48531. */
  48532. function assertInfinite(mixed $actual, string $message = ''): void
  48533. {
  48534. \PHPUnit\Framework\Assert::assertInfinite(...func_get_args());
  48535. }
  48536. }
  48537. if (!function_exists('PHPUnit\Framework\assertNan')) {
  48538. /**
  48539. * Asserts that a variable is nan.
  48540. *
  48541. * @throws ExpectationFailedException
  48542. *
  48543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48544. *
  48545. * @see Assert::assertNan
  48546. */
  48547. function assertNan(mixed $actual, string $message = ''): void
  48548. {
  48549. \PHPUnit\Framework\Assert::assertNan(...func_get_args());
  48550. }
  48551. }
  48552. if (!function_exists('PHPUnit\Framework\assertObjectHasProperty')) {
  48553. /**
  48554. * Asserts that an object has a specified property.
  48555. *
  48556. * @throws ExpectationFailedException
  48557. *
  48558. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48559. *
  48560. * @see Assert::assertObjectHasProperty
  48561. */
  48562. function assertObjectHasProperty(string $propertyName, object $object, string $message = ''): void
  48563. {
  48564. \PHPUnit\Framework\Assert::assertObjectHasProperty(...func_get_args());
  48565. }
  48566. }
  48567. if (!function_exists('PHPUnit\Framework\assertObjectNotHasProperty')) {
  48568. /**
  48569. * Asserts that an object does not have a specified property.
  48570. *
  48571. * @throws ExpectationFailedException
  48572. *
  48573. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48574. *
  48575. * @see Assert::assertObjectNotHasProperty
  48576. */
  48577. function assertObjectNotHasProperty(string $propertyName, object $object, string $message = ''): void
  48578. {
  48579. \PHPUnit\Framework\Assert::assertObjectNotHasProperty(...func_get_args());
  48580. }
  48581. }
  48582. if (!function_exists('PHPUnit\Framework\assertSame')) {
  48583. /**
  48584. * Asserts that two variables have the same type and value.
  48585. * Used on objects, it asserts that two variables reference
  48586. * the same object.
  48587. *
  48588. * @throws ExpectationFailedException
  48589. *
  48590. * @psalm-template ExpectedType
  48591. *
  48592. * @psalm-param ExpectedType $expected
  48593. *
  48594. * @psalm-assert =ExpectedType $actual
  48595. *
  48596. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48597. *
  48598. * @see Assert::assertSame
  48599. */
  48600. function assertSame(mixed $expected, mixed $actual, string $message = ''): void
  48601. {
  48602. \PHPUnit\Framework\Assert::assertSame(...func_get_args());
  48603. }
  48604. }
  48605. if (!function_exists('PHPUnit\Framework\assertNotSame')) {
  48606. /**
  48607. * Asserts that two variables do not have the same type and value.
  48608. * Used on objects, it asserts that two variables do not reference
  48609. * the same object.
  48610. *
  48611. * @throws ExpectationFailedException
  48612. *
  48613. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48614. *
  48615. * @see Assert::assertNotSame
  48616. */
  48617. function assertNotSame(mixed $expected, mixed $actual, string $message = ''): void
  48618. {
  48619. \PHPUnit\Framework\Assert::assertNotSame(...func_get_args());
  48620. }
  48621. }
  48622. if (!function_exists('PHPUnit\Framework\assertInstanceOf')) {
  48623. /**
  48624. * Asserts that a variable is of a given type.
  48625. *
  48626. * @throws Exception
  48627. * @throws ExpectationFailedException
  48628. * @throws UnknownClassOrInterfaceException
  48629. *
  48630. * @psalm-template ExpectedType of object
  48631. *
  48632. * @psalm-param class-string<ExpectedType> $expected
  48633. *
  48634. * @psalm-assert =ExpectedType $actual
  48635. *
  48636. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48637. *
  48638. * @see Assert::assertInstanceOf
  48639. */
  48640. function assertInstanceOf(string $expected, mixed $actual, string $message = ''): void
  48641. {
  48642. \PHPUnit\Framework\Assert::assertInstanceOf(...func_get_args());
  48643. }
  48644. }
  48645. if (!function_exists('PHPUnit\Framework\assertNotInstanceOf')) {
  48646. /**
  48647. * Asserts that a variable is not of a given type.
  48648. *
  48649. * @throws Exception
  48650. * @throws ExpectationFailedException
  48651. *
  48652. * @psalm-template ExpectedType of object
  48653. *
  48654. * @psalm-param class-string<ExpectedType> $expected
  48655. *
  48656. * @psalm-assert !ExpectedType $actual
  48657. *
  48658. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48659. *
  48660. * @see Assert::assertNotInstanceOf
  48661. */
  48662. function assertNotInstanceOf(string $expected, mixed $actual, string $message = ''): void
  48663. {
  48664. \PHPUnit\Framework\Assert::assertNotInstanceOf(...func_get_args());
  48665. }
  48666. }
  48667. if (!function_exists('PHPUnit\Framework\assertIsArray')) {
  48668. /**
  48669. * Asserts that a variable is of type array.
  48670. *
  48671. * @throws Exception
  48672. * @throws ExpectationFailedException
  48673. *
  48674. * @psalm-assert array $actual
  48675. *
  48676. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48677. *
  48678. * @see Assert::assertIsArray
  48679. */
  48680. function assertIsArray(mixed $actual, string $message = ''): void
  48681. {
  48682. \PHPUnit\Framework\Assert::assertIsArray(...func_get_args());
  48683. }
  48684. }
  48685. if (!function_exists('PHPUnit\Framework\assertIsBool')) {
  48686. /**
  48687. * Asserts that a variable is of type bool.
  48688. *
  48689. * @throws Exception
  48690. * @throws ExpectationFailedException
  48691. *
  48692. * @psalm-assert bool $actual
  48693. *
  48694. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48695. *
  48696. * @see Assert::assertIsBool
  48697. */
  48698. function assertIsBool(mixed $actual, string $message = ''): void
  48699. {
  48700. \PHPUnit\Framework\Assert::assertIsBool(...func_get_args());
  48701. }
  48702. }
  48703. if (!function_exists('PHPUnit\Framework\assertIsFloat')) {
  48704. /**
  48705. * Asserts that a variable is of type float.
  48706. *
  48707. * @throws Exception
  48708. * @throws ExpectationFailedException
  48709. *
  48710. * @psalm-assert float $actual
  48711. *
  48712. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48713. *
  48714. * @see Assert::assertIsFloat
  48715. */
  48716. function assertIsFloat(mixed $actual, string $message = ''): void
  48717. {
  48718. \PHPUnit\Framework\Assert::assertIsFloat(...func_get_args());
  48719. }
  48720. }
  48721. if (!function_exists('PHPUnit\Framework\assertIsInt')) {
  48722. /**
  48723. * Asserts that a variable is of type int.
  48724. *
  48725. * @throws Exception
  48726. * @throws ExpectationFailedException
  48727. *
  48728. * @psalm-assert int $actual
  48729. *
  48730. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48731. *
  48732. * @see Assert::assertIsInt
  48733. */
  48734. function assertIsInt(mixed $actual, string $message = ''): void
  48735. {
  48736. \PHPUnit\Framework\Assert::assertIsInt(...func_get_args());
  48737. }
  48738. }
  48739. if (!function_exists('PHPUnit\Framework\assertIsNumeric')) {
  48740. /**
  48741. * Asserts that a variable is of type numeric.
  48742. *
  48743. * @throws Exception
  48744. * @throws ExpectationFailedException
  48745. *
  48746. * @psalm-assert numeric $actual
  48747. *
  48748. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48749. *
  48750. * @see Assert::assertIsNumeric
  48751. */
  48752. function assertIsNumeric(mixed $actual, string $message = ''): void
  48753. {
  48754. \PHPUnit\Framework\Assert::assertIsNumeric(...func_get_args());
  48755. }
  48756. }
  48757. if (!function_exists('PHPUnit\Framework\assertIsObject')) {
  48758. /**
  48759. * Asserts that a variable is of type object.
  48760. *
  48761. * @throws Exception
  48762. * @throws ExpectationFailedException
  48763. *
  48764. * @psalm-assert object $actual
  48765. *
  48766. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48767. *
  48768. * @see Assert::assertIsObject
  48769. */
  48770. function assertIsObject(mixed $actual, string $message = ''): void
  48771. {
  48772. \PHPUnit\Framework\Assert::assertIsObject(...func_get_args());
  48773. }
  48774. }
  48775. if (!function_exists('PHPUnit\Framework\assertIsResource')) {
  48776. /**
  48777. * Asserts that a variable is of type resource.
  48778. *
  48779. * @throws Exception
  48780. * @throws ExpectationFailedException
  48781. *
  48782. * @psalm-assert resource $actual
  48783. *
  48784. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48785. *
  48786. * @see Assert::assertIsResource
  48787. */
  48788. function assertIsResource(mixed $actual, string $message = ''): void
  48789. {
  48790. \PHPUnit\Framework\Assert::assertIsResource(...func_get_args());
  48791. }
  48792. }
  48793. if (!function_exists('PHPUnit\Framework\assertIsClosedResource')) {
  48794. /**
  48795. * Asserts that a variable is of type resource and is closed.
  48796. *
  48797. * @throws Exception
  48798. * @throws ExpectationFailedException
  48799. *
  48800. * @psalm-assert resource $actual
  48801. *
  48802. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48803. *
  48804. * @see Assert::assertIsClosedResource
  48805. */
  48806. function assertIsClosedResource(mixed $actual, string $message = ''): void
  48807. {
  48808. \PHPUnit\Framework\Assert::assertIsClosedResource(...func_get_args());
  48809. }
  48810. }
  48811. if (!function_exists('PHPUnit\Framework\assertIsString')) {
  48812. /**
  48813. * Asserts that a variable is of type string.
  48814. *
  48815. * @throws Exception
  48816. * @throws ExpectationFailedException
  48817. *
  48818. * @psalm-assert string $actual
  48819. *
  48820. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48821. *
  48822. * @see Assert::assertIsString
  48823. */
  48824. function assertIsString(mixed $actual, string $message = ''): void
  48825. {
  48826. \PHPUnit\Framework\Assert::assertIsString(...func_get_args());
  48827. }
  48828. }
  48829. if (!function_exists('PHPUnit\Framework\assertIsScalar')) {
  48830. /**
  48831. * Asserts that a variable is of type scalar.
  48832. *
  48833. * @throws Exception
  48834. * @throws ExpectationFailedException
  48835. *
  48836. * @psalm-assert scalar $actual
  48837. *
  48838. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48839. *
  48840. * @see Assert::assertIsScalar
  48841. */
  48842. function assertIsScalar(mixed $actual, string $message = ''): void
  48843. {
  48844. \PHPUnit\Framework\Assert::assertIsScalar(...func_get_args());
  48845. }
  48846. }
  48847. if (!function_exists('PHPUnit\Framework\assertIsCallable')) {
  48848. /**
  48849. * Asserts that a variable is of type callable.
  48850. *
  48851. * @throws Exception
  48852. * @throws ExpectationFailedException
  48853. *
  48854. * @psalm-assert callable $actual
  48855. *
  48856. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48857. *
  48858. * @see Assert::assertIsCallable
  48859. */
  48860. function assertIsCallable(mixed $actual, string $message = ''): void
  48861. {
  48862. \PHPUnit\Framework\Assert::assertIsCallable(...func_get_args());
  48863. }
  48864. }
  48865. if (!function_exists('PHPUnit\Framework\assertIsIterable')) {
  48866. /**
  48867. * Asserts that a variable is of type iterable.
  48868. *
  48869. * @throws Exception
  48870. * @throws ExpectationFailedException
  48871. *
  48872. * @psalm-assert iterable $actual
  48873. *
  48874. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48875. *
  48876. * @see Assert::assertIsIterable
  48877. */
  48878. function assertIsIterable(mixed $actual, string $message = ''): void
  48879. {
  48880. \PHPUnit\Framework\Assert::assertIsIterable(...func_get_args());
  48881. }
  48882. }
  48883. if (!function_exists('PHPUnit\Framework\assertIsNotArray')) {
  48884. /**
  48885. * Asserts that a variable is not of type array.
  48886. *
  48887. * @throws Exception
  48888. * @throws ExpectationFailedException
  48889. *
  48890. * @psalm-assert !array $actual
  48891. *
  48892. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48893. *
  48894. * @see Assert::assertIsNotArray
  48895. */
  48896. function assertIsNotArray(mixed $actual, string $message = ''): void
  48897. {
  48898. \PHPUnit\Framework\Assert::assertIsNotArray(...func_get_args());
  48899. }
  48900. }
  48901. if (!function_exists('PHPUnit\Framework\assertIsNotBool')) {
  48902. /**
  48903. * Asserts that a variable is not of type bool.
  48904. *
  48905. * @throws Exception
  48906. * @throws ExpectationFailedException
  48907. *
  48908. * @psalm-assert !bool $actual
  48909. *
  48910. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48911. *
  48912. * @see Assert::assertIsNotBool
  48913. */
  48914. function assertIsNotBool(mixed $actual, string $message = ''): void
  48915. {
  48916. \PHPUnit\Framework\Assert::assertIsNotBool(...func_get_args());
  48917. }
  48918. }
  48919. if (!function_exists('PHPUnit\Framework\assertIsNotFloat')) {
  48920. /**
  48921. * Asserts that a variable is not of type float.
  48922. *
  48923. * @throws Exception
  48924. * @throws ExpectationFailedException
  48925. *
  48926. * @psalm-assert !float $actual
  48927. *
  48928. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48929. *
  48930. * @see Assert::assertIsNotFloat
  48931. */
  48932. function assertIsNotFloat(mixed $actual, string $message = ''): void
  48933. {
  48934. \PHPUnit\Framework\Assert::assertIsNotFloat(...func_get_args());
  48935. }
  48936. }
  48937. if (!function_exists('PHPUnit\Framework\assertIsNotInt')) {
  48938. /**
  48939. * Asserts that a variable is not of type int.
  48940. *
  48941. * @throws Exception
  48942. * @throws ExpectationFailedException
  48943. *
  48944. * @psalm-assert !int $actual
  48945. *
  48946. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48947. *
  48948. * @see Assert::assertIsNotInt
  48949. */
  48950. function assertIsNotInt(mixed $actual, string $message = ''): void
  48951. {
  48952. \PHPUnit\Framework\Assert::assertIsNotInt(...func_get_args());
  48953. }
  48954. }
  48955. if (!function_exists('PHPUnit\Framework\assertIsNotNumeric')) {
  48956. /**
  48957. * Asserts that a variable is not of type numeric.
  48958. *
  48959. * @throws Exception
  48960. * @throws ExpectationFailedException
  48961. *
  48962. * @psalm-assert !numeric $actual
  48963. *
  48964. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48965. *
  48966. * @see Assert::assertIsNotNumeric
  48967. */
  48968. function assertIsNotNumeric(mixed $actual, string $message = ''): void
  48969. {
  48970. \PHPUnit\Framework\Assert::assertIsNotNumeric(...func_get_args());
  48971. }
  48972. }
  48973. if (!function_exists('PHPUnit\Framework\assertIsNotObject')) {
  48974. /**
  48975. * Asserts that a variable is not of type object.
  48976. *
  48977. * @throws Exception
  48978. * @throws ExpectationFailedException
  48979. *
  48980. * @psalm-assert !object $actual
  48981. *
  48982. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  48983. *
  48984. * @see Assert::assertIsNotObject
  48985. */
  48986. function assertIsNotObject(mixed $actual, string $message = ''): void
  48987. {
  48988. \PHPUnit\Framework\Assert::assertIsNotObject(...func_get_args());
  48989. }
  48990. }
  48991. if (!function_exists('PHPUnit\Framework\assertIsNotResource')) {
  48992. /**
  48993. * Asserts that a variable is not of type resource.
  48994. *
  48995. * @throws Exception
  48996. * @throws ExpectationFailedException
  48997. *
  48998. * @psalm-assert !resource $actual
  48999. *
  49000. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49001. *
  49002. * @see Assert::assertIsNotResource
  49003. */
  49004. function assertIsNotResource(mixed $actual, string $message = ''): void
  49005. {
  49006. \PHPUnit\Framework\Assert::assertIsNotResource(...func_get_args());
  49007. }
  49008. }
  49009. if (!function_exists('PHPUnit\Framework\assertIsNotClosedResource')) {
  49010. /**
  49011. * Asserts that a variable is not of type resource.
  49012. *
  49013. * @throws Exception
  49014. * @throws ExpectationFailedException
  49015. *
  49016. * @psalm-assert !resource $actual
  49017. *
  49018. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49019. *
  49020. * @see Assert::assertIsNotClosedResource
  49021. */
  49022. function assertIsNotClosedResource(mixed $actual, string $message = ''): void
  49023. {
  49024. \PHPUnit\Framework\Assert::assertIsNotClosedResource(...func_get_args());
  49025. }
  49026. }
  49027. if (!function_exists('PHPUnit\Framework\assertIsNotString')) {
  49028. /**
  49029. * Asserts that a variable is not of type string.
  49030. *
  49031. * @throws Exception
  49032. * @throws ExpectationFailedException
  49033. *
  49034. * @psalm-assert !string $actual
  49035. *
  49036. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49037. *
  49038. * @see Assert::assertIsNotString
  49039. */
  49040. function assertIsNotString(mixed $actual, string $message = ''): void
  49041. {
  49042. \PHPUnit\Framework\Assert::assertIsNotString(...func_get_args());
  49043. }
  49044. }
  49045. if (!function_exists('PHPUnit\Framework\assertIsNotScalar')) {
  49046. /**
  49047. * Asserts that a variable is not of type scalar.
  49048. *
  49049. * @throws Exception
  49050. * @throws ExpectationFailedException
  49051. *
  49052. * @psalm-assert !scalar $actual
  49053. *
  49054. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49055. *
  49056. * @see Assert::assertIsNotScalar
  49057. */
  49058. function assertIsNotScalar(mixed $actual, string $message = ''): void
  49059. {
  49060. \PHPUnit\Framework\Assert::assertIsNotScalar(...func_get_args());
  49061. }
  49062. }
  49063. if (!function_exists('PHPUnit\Framework\assertIsNotCallable')) {
  49064. /**
  49065. * Asserts that a variable is not of type callable.
  49066. *
  49067. * @throws Exception
  49068. * @throws ExpectationFailedException
  49069. *
  49070. * @psalm-assert !callable $actual
  49071. *
  49072. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49073. *
  49074. * @see Assert::assertIsNotCallable
  49075. */
  49076. function assertIsNotCallable(mixed $actual, string $message = ''): void
  49077. {
  49078. \PHPUnit\Framework\Assert::assertIsNotCallable(...func_get_args());
  49079. }
  49080. }
  49081. if (!function_exists('PHPUnit\Framework\assertIsNotIterable')) {
  49082. /**
  49083. * Asserts that a variable is not of type iterable.
  49084. *
  49085. * @throws Exception
  49086. * @throws ExpectationFailedException
  49087. *
  49088. * @psalm-assert !iterable $actual
  49089. *
  49090. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49091. *
  49092. * @see Assert::assertIsNotIterable
  49093. */
  49094. function assertIsNotIterable(mixed $actual, string $message = ''): void
  49095. {
  49096. \PHPUnit\Framework\Assert::assertIsNotIterable(...func_get_args());
  49097. }
  49098. }
  49099. if (!function_exists('PHPUnit\Framework\assertMatchesRegularExpression')) {
  49100. /**
  49101. * Asserts that a string matches a given regular expression.
  49102. *
  49103. * @throws ExpectationFailedException
  49104. *
  49105. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49106. *
  49107. * @see Assert::assertMatchesRegularExpression
  49108. */
  49109. function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
  49110. {
  49111. \PHPUnit\Framework\Assert::assertMatchesRegularExpression(...func_get_args());
  49112. }
  49113. }
  49114. if (!function_exists('PHPUnit\Framework\assertDoesNotMatchRegularExpression')) {
  49115. /**
  49116. * Asserts that a string does not match a given regular expression.
  49117. *
  49118. * @throws ExpectationFailedException
  49119. *
  49120. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49121. *
  49122. * @see Assert::assertDoesNotMatchRegularExpression
  49123. */
  49124. function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
  49125. {
  49126. \PHPUnit\Framework\Assert::assertDoesNotMatchRegularExpression(...func_get_args());
  49127. }
  49128. }
  49129. if (!function_exists('PHPUnit\Framework\assertSameSize')) {
  49130. /**
  49131. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  49132. * is the same.
  49133. *
  49134. * @throws Exception
  49135. * @throws ExpectationFailedException
  49136. * @throws GeneratorNotSupportedException
  49137. *
  49138. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49139. *
  49140. * @see Assert::assertSameSize
  49141. */
  49142. function assertSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
  49143. {
  49144. \PHPUnit\Framework\Assert::assertSameSize(...func_get_args());
  49145. }
  49146. }
  49147. if (!function_exists('PHPUnit\Framework\assertNotSameSize')) {
  49148. /**
  49149. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  49150. * is not the same.
  49151. *
  49152. * @throws Exception
  49153. * @throws ExpectationFailedException
  49154. * @throws GeneratorNotSupportedException
  49155. *
  49156. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49157. *
  49158. * @see Assert::assertNotSameSize
  49159. */
  49160. function assertNotSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
  49161. {
  49162. \PHPUnit\Framework\Assert::assertNotSameSize(...func_get_args());
  49163. }
  49164. }
  49165. if (!function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringLineEndings')) {
  49166. /**
  49167. * @throws ExpectationFailedException
  49168. *
  49169. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49170. *
  49171. * @see Assert::assertStringContainsStringIgnoringLineEndings
  49172. */
  49173. function assertStringContainsStringIgnoringLineEndings(string $needle, string $haystack, string $message = ''): void
  49174. {
  49175. \PHPUnit\Framework\Assert::assertStringContainsStringIgnoringLineEndings(...func_get_args());
  49176. }
  49177. }
  49178. if (!function_exists('PHPUnit\Framework\assertStringEqualsStringIgnoringLineEndings')) {
  49179. /**
  49180. * Asserts that two strings are equal except for line endings.
  49181. *
  49182. * @throws ExpectationFailedException
  49183. *
  49184. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49185. *
  49186. * @see Assert::assertStringEqualsStringIgnoringLineEndings
  49187. */
  49188. function assertStringEqualsStringIgnoringLineEndings(string $expected, string $actual, string $message = ''): void
  49189. {
  49190. \PHPUnit\Framework\Assert::assertStringEqualsStringIgnoringLineEndings(...func_get_args());
  49191. }
  49192. }
  49193. if (!function_exists('PHPUnit\Framework\assertFileMatchesFormat')) {
  49194. /**
  49195. * Asserts that a string matches a given format string.
  49196. *
  49197. * @throws ExpectationFailedException
  49198. *
  49199. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49200. *
  49201. * @see Assert::assertFileMatchesFormat
  49202. */
  49203. function assertFileMatchesFormat(string $format, string $actualFile, string $message = ''): void
  49204. {
  49205. \PHPUnit\Framework\Assert::assertFileMatchesFormat(...func_get_args());
  49206. }
  49207. }
  49208. if (!function_exists('PHPUnit\Framework\assertFileMatchesFormatFile')) {
  49209. /**
  49210. * Asserts that a string matches a given format string.
  49211. *
  49212. * @throws ExpectationFailedException
  49213. *
  49214. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49215. *
  49216. * @see Assert::assertFileMatchesFormatFile
  49217. */
  49218. function assertFileMatchesFormatFile(string $formatFile, string $actualFile, string $message = ''): void
  49219. {
  49220. \PHPUnit\Framework\Assert::assertFileMatchesFormatFile(...func_get_args());
  49221. }
  49222. }
  49223. if (!function_exists('PHPUnit\Framework\assertStringMatchesFormat')) {
  49224. /**
  49225. * Asserts that a string matches a given format string.
  49226. *
  49227. * @throws ExpectationFailedException
  49228. *
  49229. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49230. *
  49231. * @see Assert::assertStringMatchesFormat
  49232. */
  49233. function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
  49234. {
  49235. \PHPUnit\Framework\Assert::assertStringMatchesFormat(...func_get_args());
  49236. }
  49237. }
  49238. if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormat')) {
  49239. /**
  49240. * Asserts that a string does not match a given format string.
  49241. *
  49242. * @throws ExpectationFailedException
  49243. *
  49244. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
  49245. *
  49246. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49247. *
  49248. * @see Assert::assertStringNotMatchesFormat
  49249. */
  49250. function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
  49251. {
  49252. \PHPUnit\Framework\Assert::assertStringNotMatchesFormat(...func_get_args());
  49253. }
  49254. }
  49255. if (!function_exists('PHPUnit\Framework\assertStringMatchesFormatFile')) {
  49256. /**
  49257. * Asserts that a string matches a given format file.
  49258. *
  49259. * @throws ExpectationFailedException
  49260. *
  49261. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49262. *
  49263. * @see Assert::assertStringMatchesFormatFile
  49264. */
  49265. function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
  49266. {
  49267. \PHPUnit\Framework\Assert::assertStringMatchesFormatFile(...func_get_args());
  49268. }
  49269. }
  49270. if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormatFile')) {
  49271. /**
  49272. * Asserts that a string does not match a given format string.
  49273. *
  49274. * @throws ExpectationFailedException
  49275. *
  49276. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
  49277. *
  49278. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49279. *
  49280. * @see Assert::assertStringNotMatchesFormatFile
  49281. */
  49282. function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
  49283. {
  49284. \PHPUnit\Framework\Assert::assertStringNotMatchesFormatFile(...func_get_args());
  49285. }
  49286. }
  49287. if (!function_exists('PHPUnit\Framework\assertStringStartsWith')) {
  49288. /**
  49289. * Asserts that a string starts with a given prefix.
  49290. *
  49291. * @psalm-param non-empty-string $prefix
  49292. *
  49293. * @throws ExpectationFailedException
  49294. * @throws InvalidArgumentException
  49295. *
  49296. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49297. *
  49298. * @see Assert::assertStringStartsWith
  49299. */
  49300. function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
  49301. {
  49302. \PHPUnit\Framework\Assert::assertStringStartsWith(...func_get_args());
  49303. }
  49304. }
  49305. if (!function_exists('PHPUnit\Framework\assertStringStartsNotWith')) {
  49306. /**
  49307. * Asserts that a string starts not with a given prefix.
  49308. *
  49309. * @psalm-param non-empty-string $prefix
  49310. *
  49311. * @throws ExpectationFailedException
  49312. * @throws InvalidArgumentException
  49313. *
  49314. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49315. *
  49316. * @see Assert::assertStringStartsNotWith
  49317. */
  49318. function assertStringStartsNotWith(string $prefix, string $string, string $message = ''): void
  49319. {
  49320. \PHPUnit\Framework\Assert::assertStringStartsNotWith(...func_get_args());
  49321. }
  49322. }
  49323. if (!function_exists('PHPUnit\Framework\assertStringContainsString')) {
  49324. /**
  49325. * @throws ExpectationFailedException
  49326. *
  49327. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49328. *
  49329. * @see Assert::assertStringContainsString
  49330. */
  49331. function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
  49332. {
  49333. \PHPUnit\Framework\Assert::assertStringContainsString(...func_get_args());
  49334. }
  49335. }
  49336. if (!function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringCase')) {
  49337. /**
  49338. * @throws ExpectationFailedException
  49339. *
  49340. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49341. *
  49342. * @see Assert::assertStringContainsStringIgnoringCase
  49343. */
  49344. function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
  49345. {
  49346. \PHPUnit\Framework\Assert::assertStringContainsStringIgnoringCase(...func_get_args());
  49347. }
  49348. }
  49349. if (!function_exists('PHPUnit\Framework\assertStringNotContainsString')) {
  49350. /**
  49351. * @throws ExpectationFailedException
  49352. *
  49353. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49354. *
  49355. * @see Assert::assertStringNotContainsString
  49356. */
  49357. function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
  49358. {
  49359. \PHPUnit\Framework\Assert::assertStringNotContainsString(...func_get_args());
  49360. }
  49361. }
  49362. if (!function_exists('PHPUnit\Framework\assertStringNotContainsStringIgnoringCase')) {
  49363. /**
  49364. * @throws ExpectationFailedException
  49365. *
  49366. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49367. *
  49368. * @see Assert::assertStringNotContainsStringIgnoringCase
  49369. */
  49370. function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
  49371. {
  49372. \PHPUnit\Framework\Assert::assertStringNotContainsStringIgnoringCase(...func_get_args());
  49373. }
  49374. }
  49375. if (!function_exists('PHPUnit\Framework\assertStringEndsWith')) {
  49376. /**
  49377. * Asserts that a string ends with a given suffix.
  49378. *
  49379. * @psalm-param non-empty-string $suffix
  49380. *
  49381. * @throws ExpectationFailedException
  49382. * @throws InvalidArgumentException
  49383. *
  49384. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49385. *
  49386. * @see Assert::assertStringEndsWith
  49387. */
  49388. function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
  49389. {
  49390. \PHPUnit\Framework\Assert::assertStringEndsWith(...func_get_args());
  49391. }
  49392. }
  49393. if (!function_exists('PHPUnit\Framework\assertStringEndsNotWith')) {
  49394. /**
  49395. * Asserts that a string ends not with a given suffix.
  49396. *
  49397. * @psalm-param non-empty-string $suffix
  49398. *
  49399. * @throws ExpectationFailedException
  49400. * @throws InvalidArgumentException
  49401. *
  49402. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49403. *
  49404. * @see Assert::assertStringEndsNotWith
  49405. */
  49406. function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
  49407. {
  49408. \PHPUnit\Framework\Assert::assertStringEndsNotWith(...func_get_args());
  49409. }
  49410. }
  49411. if (!function_exists('PHPUnit\Framework\assertXmlFileEqualsXmlFile')) {
  49412. /**
  49413. * Asserts that two XML files are equal.
  49414. *
  49415. * @throws Exception
  49416. * @throws ExpectationFailedException
  49417. * @throws XmlException
  49418. *
  49419. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49420. *
  49421. * @see Assert::assertXmlFileEqualsXmlFile
  49422. */
  49423. function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
  49424. {
  49425. \PHPUnit\Framework\Assert::assertXmlFileEqualsXmlFile(...func_get_args());
  49426. }
  49427. }
  49428. if (!function_exists('PHPUnit\Framework\assertXmlFileNotEqualsXmlFile')) {
  49429. /**
  49430. * Asserts that two XML files are not equal.
  49431. *
  49432. * @throws \PHPUnit\Util\Exception
  49433. * @throws ExpectationFailedException
  49434. *
  49435. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49436. *
  49437. * @see Assert::assertXmlFileNotEqualsXmlFile
  49438. */
  49439. function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
  49440. {
  49441. \PHPUnit\Framework\Assert::assertXmlFileNotEqualsXmlFile(...func_get_args());
  49442. }
  49443. }
  49444. if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlFile')) {
  49445. /**
  49446. * Asserts that two XML documents are equal.
  49447. *
  49448. * @throws ExpectationFailedException
  49449. * @throws XmlException
  49450. *
  49451. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49452. *
  49453. * @see Assert::assertXmlStringEqualsXmlFile
  49454. */
  49455. function assertXmlStringEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
  49456. {
  49457. \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlFile(...func_get_args());
  49458. }
  49459. }
  49460. if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlFile')) {
  49461. /**
  49462. * Asserts that two XML documents are not equal.
  49463. *
  49464. * @throws ExpectationFailedException
  49465. * @throws XmlException
  49466. *
  49467. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49468. *
  49469. * @see Assert::assertXmlStringNotEqualsXmlFile
  49470. */
  49471. function assertXmlStringNotEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
  49472. {
  49473. \PHPUnit\Framework\Assert::assertXmlStringNotEqualsXmlFile(...func_get_args());
  49474. }
  49475. }
  49476. if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlString')) {
  49477. /**
  49478. * Asserts that two XML documents are equal.
  49479. *
  49480. * @throws ExpectationFailedException
  49481. * @throws XmlException
  49482. *
  49483. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49484. *
  49485. * @see Assert::assertXmlStringEqualsXmlString
  49486. */
  49487. function assertXmlStringEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
  49488. {
  49489. \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlString(...func_get_args());
  49490. }
  49491. }
  49492. if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlString')) {
  49493. /**
  49494. * Asserts that two XML documents are not equal.
  49495. *
  49496. * @throws ExpectationFailedException
  49497. * @throws XmlException
  49498. *
  49499. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49500. *
  49501. * @see Assert::assertXmlStringNotEqualsXmlString
  49502. */
  49503. function assertXmlStringNotEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
  49504. {
  49505. \PHPUnit\Framework\Assert::assertXmlStringNotEqualsXmlString(...func_get_args());
  49506. }
  49507. }
  49508. if (!function_exists('PHPUnit\Framework\assertThat')) {
  49509. /**
  49510. * Evaluates a PHPUnit\Framework\Constraint matcher object.
  49511. *
  49512. * @throws ExpectationFailedException
  49513. *
  49514. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49515. *
  49516. * @see Assert::assertThat
  49517. */
  49518. function assertThat(mixed $value, Constraint $constraint, string $message = ''): void
  49519. {
  49520. \PHPUnit\Framework\Assert::assertThat(...func_get_args());
  49521. }
  49522. }
  49523. if (!function_exists('PHPUnit\Framework\assertJson')) {
  49524. /**
  49525. * Asserts that a string is a valid JSON string.
  49526. *
  49527. * @throws ExpectationFailedException
  49528. *
  49529. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49530. *
  49531. * @see Assert::assertJson
  49532. */
  49533. function assertJson(string $actual, string $message = ''): void
  49534. {
  49535. \PHPUnit\Framework\Assert::assertJson(...func_get_args());
  49536. }
  49537. }
  49538. if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonString')) {
  49539. /**
  49540. * Asserts that two given JSON encoded objects or arrays are equal.
  49541. *
  49542. * @throws ExpectationFailedException
  49543. *
  49544. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49545. *
  49546. * @see Assert::assertJsonStringEqualsJsonString
  49547. */
  49548. function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
  49549. {
  49550. \PHPUnit\Framework\Assert::assertJsonStringEqualsJsonString(...func_get_args());
  49551. }
  49552. }
  49553. if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonString')) {
  49554. /**
  49555. * Asserts that two given JSON encoded objects or arrays are not equal.
  49556. *
  49557. * @throws ExpectationFailedException
  49558. *
  49559. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49560. *
  49561. * @see Assert::assertJsonStringNotEqualsJsonString
  49562. */
  49563. function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
  49564. {
  49565. \PHPUnit\Framework\Assert::assertJsonStringNotEqualsJsonString(...func_get_args());
  49566. }
  49567. }
  49568. if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonFile')) {
  49569. /**
  49570. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  49571. *
  49572. * @throws ExpectationFailedException
  49573. *
  49574. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49575. *
  49576. * @see Assert::assertJsonStringEqualsJsonFile
  49577. */
  49578. function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
  49579. {
  49580. \PHPUnit\Framework\Assert::assertJsonStringEqualsJsonFile(...func_get_args());
  49581. }
  49582. }
  49583. if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonFile')) {
  49584. /**
  49585. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  49586. *
  49587. * @throws ExpectationFailedException
  49588. *
  49589. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49590. *
  49591. * @see Assert::assertJsonStringNotEqualsJsonFile
  49592. */
  49593. function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
  49594. {
  49595. \PHPUnit\Framework\Assert::assertJsonStringNotEqualsJsonFile(...func_get_args());
  49596. }
  49597. }
  49598. if (!function_exists('PHPUnit\Framework\assertJsonFileEqualsJsonFile')) {
  49599. /**
  49600. * Asserts that two JSON files are equal.
  49601. *
  49602. * @throws ExpectationFailedException
  49603. *
  49604. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49605. *
  49606. * @see Assert::assertJsonFileEqualsJsonFile
  49607. */
  49608. function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
  49609. {
  49610. \PHPUnit\Framework\Assert::assertJsonFileEqualsJsonFile(...func_get_args());
  49611. }
  49612. }
  49613. if (!function_exists('PHPUnit\Framework\assertJsonFileNotEqualsJsonFile')) {
  49614. /**
  49615. * Asserts that two JSON files are not equal.
  49616. *
  49617. * @throws ExpectationFailedException
  49618. *
  49619. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  49620. *
  49621. * @see Assert::assertJsonFileNotEqualsJsonFile
  49622. */
  49623. function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
  49624. {
  49625. \PHPUnit\Framework\Assert::assertJsonFileNotEqualsJsonFile(...func_get_args());
  49626. }
  49627. }
  49628. if (!function_exists('PHPUnit\Framework\logicalAnd')) {
  49629. function logicalAnd(mixed ...$constraints): LogicalAnd
  49630. {
  49631. return \PHPUnit\Framework\Assert::logicalAnd(...func_get_args());
  49632. }
  49633. }
  49634. if (!function_exists('PHPUnit\Framework\logicalOr')) {
  49635. function logicalOr(mixed ...$constraints): LogicalOr
  49636. {
  49637. return \PHPUnit\Framework\Assert::logicalOr(...func_get_args());
  49638. }
  49639. }
  49640. if (!function_exists('PHPUnit\Framework\logicalNot')) {
  49641. function logicalNot(Constraint $constraint): LogicalNot
  49642. {
  49643. return \PHPUnit\Framework\Assert::logicalNot(...func_get_args());
  49644. }
  49645. }
  49646. if (!function_exists('PHPUnit\Framework\logicalXor')) {
  49647. function logicalXor(mixed ...$constraints): LogicalXor
  49648. {
  49649. return \PHPUnit\Framework\Assert::logicalXor(...func_get_args());
  49650. }
  49651. }
  49652. if (!function_exists('PHPUnit\Framework\anything')) {
  49653. function anything(): IsAnything
  49654. {
  49655. return \PHPUnit\Framework\Assert::anything(...func_get_args());
  49656. }
  49657. }
  49658. if (!function_exists('PHPUnit\Framework\isTrue')) {
  49659. function isTrue(): IsTrue
  49660. {
  49661. return \PHPUnit\Framework\Assert::isTrue(...func_get_args());
  49662. }
  49663. }
  49664. if (!function_exists('PHPUnit\Framework\isFalse')) {
  49665. function isFalse(): IsFalse
  49666. {
  49667. return \PHPUnit\Framework\Assert::isFalse(...func_get_args());
  49668. }
  49669. }
  49670. if (!function_exists('PHPUnit\Framework\isJson')) {
  49671. function isJson(): IsJson
  49672. {
  49673. return \PHPUnit\Framework\Assert::isJson(...func_get_args());
  49674. }
  49675. }
  49676. if (!function_exists('PHPUnit\Framework\isNull')) {
  49677. function isNull(): IsNull
  49678. {
  49679. return \PHPUnit\Framework\Assert::isNull(...func_get_args());
  49680. }
  49681. }
  49682. if (!function_exists('PHPUnit\Framework\isFinite')) {
  49683. function isFinite(): IsFinite
  49684. {
  49685. return \PHPUnit\Framework\Assert::isFinite(...func_get_args());
  49686. }
  49687. }
  49688. if (!function_exists('PHPUnit\Framework\isInfinite')) {
  49689. function isInfinite(): IsInfinite
  49690. {
  49691. return \PHPUnit\Framework\Assert::isInfinite(...func_get_args());
  49692. }
  49693. }
  49694. if (!function_exists('PHPUnit\Framework\isNan')) {
  49695. function isNan(): IsNan
  49696. {
  49697. return \PHPUnit\Framework\Assert::isNan(...func_get_args());
  49698. }
  49699. }
  49700. if (!function_exists('PHPUnit\Framework\containsEqual')) {
  49701. function containsEqual(mixed $value): TraversableContainsEqual
  49702. {
  49703. return \PHPUnit\Framework\Assert::containsEqual(...func_get_args());
  49704. }
  49705. }
  49706. if (!function_exists('PHPUnit\Framework\containsIdentical')) {
  49707. function containsIdentical(mixed $value): TraversableContainsIdentical
  49708. {
  49709. return \PHPUnit\Framework\Assert::containsIdentical(...func_get_args());
  49710. }
  49711. }
  49712. if (!function_exists('PHPUnit\Framework\containsOnly')) {
  49713. function containsOnly(string $type): TraversableContainsOnly
  49714. {
  49715. return \PHPUnit\Framework\Assert::containsOnly(...func_get_args());
  49716. }
  49717. }
  49718. if (!function_exists('PHPUnit\Framework\containsOnlyInstancesOf')) {
  49719. function containsOnlyInstancesOf(string $className): TraversableContainsOnly
  49720. {
  49721. return \PHPUnit\Framework\Assert::containsOnlyInstancesOf(...func_get_args());
  49722. }
  49723. }
  49724. if (!function_exists('PHPUnit\Framework\arrayHasKey')) {
  49725. function arrayHasKey(mixed $key): ArrayHasKey
  49726. {
  49727. return \PHPUnit\Framework\Assert::arrayHasKey(...func_get_args());
  49728. }
  49729. }
  49730. if (!function_exists('PHPUnit\Framework\isList')) {
  49731. function isList(): IsList
  49732. {
  49733. return \PHPUnit\Framework\Assert::isList(...func_get_args());
  49734. }
  49735. }
  49736. if (!function_exists('PHPUnit\Framework\equalTo')) {
  49737. function equalTo(mixed $value): IsEqual
  49738. {
  49739. return \PHPUnit\Framework\Assert::equalTo(...func_get_args());
  49740. }
  49741. }
  49742. if (!function_exists('PHPUnit\Framework\equalToCanonicalizing')) {
  49743. function equalToCanonicalizing(mixed $value): IsEqualCanonicalizing
  49744. {
  49745. return \PHPUnit\Framework\Assert::equalToCanonicalizing(...func_get_args());
  49746. }
  49747. }
  49748. if (!function_exists('PHPUnit\Framework\equalToIgnoringCase')) {
  49749. function equalToIgnoringCase(mixed $value): IsEqualIgnoringCase
  49750. {
  49751. return \PHPUnit\Framework\Assert::equalToIgnoringCase(...func_get_args());
  49752. }
  49753. }
  49754. if (!function_exists('PHPUnit\Framework\equalToWithDelta')) {
  49755. function equalToWithDelta(mixed $value, float $delta): IsEqualWithDelta
  49756. {
  49757. return \PHPUnit\Framework\Assert::equalToWithDelta(...func_get_args());
  49758. }
  49759. }
  49760. if (!function_exists('PHPUnit\Framework\isEmpty')) {
  49761. function isEmpty(): IsEmpty
  49762. {
  49763. return \PHPUnit\Framework\Assert::isEmpty(...func_get_args());
  49764. }
  49765. }
  49766. if (!function_exists('PHPUnit\Framework\isWritable')) {
  49767. function isWritable(): IsWritable
  49768. {
  49769. return \PHPUnit\Framework\Assert::isWritable(...func_get_args());
  49770. }
  49771. }
  49772. if (!function_exists('PHPUnit\Framework\isReadable')) {
  49773. function isReadable(): IsReadable
  49774. {
  49775. return \PHPUnit\Framework\Assert::isReadable(...func_get_args());
  49776. }
  49777. }
  49778. if (!function_exists('PHPUnit\Framework\directoryExists')) {
  49779. function directoryExists(): DirectoryExists
  49780. {
  49781. return \PHPUnit\Framework\Assert::directoryExists(...func_get_args());
  49782. }
  49783. }
  49784. if (!function_exists('PHPUnit\Framework\fileExists')) {
  49785. function fileExists(): FileExists
  49786. {
  49787. return \PHPUnit\Framework\Assert::fileExists(...func_get_args());
  49788. }
  49789. }
  49790. if (!function_exists('PHPUnit\Framework\greaterThan')) {
  49791. function greaterThan(mixed $value): GreaterThan
  49792. {
  49793. return \PHPUnit\Framework\Assert::greaterThan(...func_get_args());
  49794. }
  49795. }
  49796. if (!function_exists('PHPUnit\Framework\greaterThanOrEqual')) {
  49797. function greaterThanOrEqual(mixed $value): LogicalOr
  49798. {
  49799. return \PHPUnit\Framework\Assert::greaterThanOrEqual(...func_get_args());
  49800. }
  49801. }
  49802. if (!function_exists('PHPUnit\Framework\identicalTo')) {
  49803. function identicalTo(mixed $value): IsIdentical
  49804. {
  49805. return \PHPUnit\Framework\Assert::identicalTo(...func_get_args());
  49806. }
  49807. }
  49808. if (!function_exists('PHPUnit\Framework\isInstanceOf')) {
  49809. function isInstanceOf(string $className): IsInstanceOf
  49810. {
  49811. return \PHPUnit\Framework\Assert::isInstanceOf(...func_get_args());
  49812. }
  49813. }
  49814. if (!function_exists('PHPUnit\Framework\isType')) {
  49815. function isType(string $type): IsType
  49816. {
  49817. return \PHPUnit\Framework\Assert::isType(...func_get_args());
  49818. }
  49819. }
  49820. if (!function_exists('PHPUnit\Framework\lessThan')) {
  49821. function lessThan(mixed $value): LessThan
  49822. {
  49823. return \PHPUnit\Framework\Assert::lessThan(...func_get_args());
  49824. }
  49825. }
  49826. if (!function_exists('PHPUnit\Framework\lessThanOrEqual')) {
  49827. function lessThanOrEqual(mixed $value): LogicalOr
  49828. {
  49829. return \PHPUnit\Framework\Assert::lessThanOrEqual(...func_get_args());
  49830. }
  49831. }
  49832. if (!function_exists('PHPUnit\Framework\matchesRegularExpression')) {
  49833. function matchesRegularExpression(string $pattern): RegularExpression
  49834. {
  49835. return \PHPUnit\Framework\Assert::matchesRegularExpression(...func_get_args());
  49836. }
  49837. }
  49838. if (!function_exists('PHPUnit\Framework\matches')) {
  49839. function matches(string $string): StringMatchesFormatDescription
  49840. {
  49841. return \PHPUnit\Framework\Assert::matches(...func_get_args());
  49842. }
  49843. }
  49844. if (!function_exists('PHPUnit\Framework\stringStartsWith')) {
  49845. function stringStartsWith(string $prefix): StringStartsWith
  49846. {
  49847. return \PHPUnit\Framework\Assert::stringStartsWith(...func_get_args());
  49848. }
  49849. }
  49850. if (!function_exists('PHPUnit\Framework\stringContains')) {
  49851. function stringContains(string $string, bool $case = \true): StringContains
  49852. {
  49853. return \PHPUnit\Framework\Assert::stringContains(...func_get_args());
  49854. }
  49855. }
  49856. if (!function_exists('PHPUnit\Framework\stringEndsWith')) {
  49857. function stringEndsWith(string $suffix): StringEndsWith
  49858. {
  49859. return \PHPUnit\Framework\Assert::stringEndsWith(...func_get_args());
  49860. }
  49861. }
  49862. if (!function_exists('PHPUnit\Framework\stringEqualsStringIgnoringLineEndings')) {
  49863. function stringEqualsStringIgnoringLineEndings(string $string): StringEqualsStringIgnoringLineEndings
  49864. {
  49865. return \PHPUnit\Framework\Assert::stringEqualsStringIgnoringLineEndings(...func_get_args());
  49866. }
  49867. }
  49868. if (!function_exists('PHPUnit\Framework\countOf')) {
  49869. function countOf(int $count): Count
  49870. {
  49871. return \PHPUnit\Framework\Assert::countOf(...func_get_args());
  49872. }
  49873. }
  49874. if (!function_exists('PHPUnit\Framework\objectEquals')) {
  49875. function objectEquals(object $object, string $method = 'equals'): ObjectEquals
  49876. {
  49877. return \PHPUnit\Framework\Assert::objectEquals(...func_get_args());
  49878. }
  49879. }
  49880. if (!function_exists('PHPUnit\Framework\callback')) {
  49881. /**
  49882. * @psalm-template CallbackInput of mixed
  49883. *
  49884. * @psalm-param callable(CallbackInput $callback): bool $callback
  49885. *
  49886. * @psalm-return Callback<CallbackInput>
  49887. */
  49888. function callback(callable $callback): Callback
  49889. {
  49890. return \PHPUnit\Framework\Assert::callback($callback);
  49891. }
  49892. }
  49893. if (!function_exists('PHPUnit\Framework\any')) {
  49894. /**
  49895. * Returns a matcher that matches when the method is executed
  49896. * zero or more times.
  49897. */
  49898. function any(): AnyInvokedCountMatcher
  49899. {
  49900. return new AnyInvokedCountMatcher();
  49901. }
  49902. }
  49903. if (!function_exists('PHPUnit\Framework\never')) {
  49904. /**
  49905. * Returns a matcher that matches when the method is never executed.
  49906. */
  49907. function never(): InvokedCountMatcher
  49908. {
  49909. return new InvokedCountMatcher(0);
  49910. }
  49911. }
  49912. if (!function_exists('PHPUnit\Framework\atLeast')) {
  49913. /**
  49914. * Returns a matcher that matches when the method is executed
  49915. * at least N times.
  49916. */
  49917. function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
  49918. {
  49919. return new InvokedAtLeastCountMatcher($requiredInvocations);
  49920. }
  49921. }
  49922. if (!function_exists('PHPUnit\Framework\atLeastOnce')) {
  49923. /**
  49924. * Returns a matcher that matches when the method is executed at least once.
  49925. */
  49926. function atLeastOnce(): InvokedAtLeastOnceMatcher
  49927. {
  49928. return new InvokedAtLeastOnceMatcher();
  49929. }
  49930. }
  49931. if (!function_exists('PHPUnit\Framework\once')) {
  49932. /**
  49933. * Returns a matcher that matches when the method is executed exactly once.
  49934. */
  49935. function once(): InvokedCountMatcher
  49936. {
  49937. return new InvokedCountMatcher(1);
  49938. }
  49939. }
  49940. if (!function_exists('PHPUnit\Framework\exactly')) {
  49941. /**
  49942. * Returns a matcher that matches when the method is executed
  49943. * exactly $count times.
  49944. */
  49945. function exactly(int $count): InvokedCountMatcher
  49946. {
  49947. return new InvokedCountMatcher($count);
  49948. }
  49949. }
  49950. if (!function_exists('PHPUnit\Framework\atMost')) {
  49951. /**
  49952. * Returns a matcher that matches when the method is executed
  49953. * at most N times.
  49954. */
  49955. function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
  49956. {
  49957. return new InvokedAtMostCountMatcher($allowedInvocations);
  49958. }
  49959. }
  49960. if (!function_exists('PHPUnit\Framework\returnValue')) {
  49961. function returnValue(mixed $value): ReturnStub
  49962. {
  49963. return new ReturnStub($value);
  49964. }
  49965. }
  49966. if (!function_exists('PHPUnit\Framework\returnValueMap')) {
  49967. function returnValueMap(array $valueMap): ReturnValueMapStub
  49968. {
  49969. return new ReturnValueMapStub($valueMap);
  49970. }
  49971. }
  49972. if (!function_exists('PHPUnit\Framework\returnArgument')) {
  49973. function returnArgument(int $argumentIndex): ReturnArgumentStub
  49974. {
  49975. return new ReturnArgumentStub($argumentIndex);
  49976. }
  49977. }
  49978. if (!function_exists('PHPUnit\Framework\returnCallback')) {
  49979. function returnCallback(callable $callback): ReturnCallbackStub
  49980. {
  49981. return new ReturnCallbackStub($callback);
  49982. }
  49983. }
  49984. if (!function_exists('PHPUnit\Framework\returnSelf')) {
  49985. /**
  49986. * Returns the current object.
  49987. *
  49988. * This method is useful when mocking a fluent interface.
  49989. */
  49990. function returnSelf(): ReturnSelfStub
  49991. {
  49992. return new ReturnSelfStub();
  49993. }
  49994. }
  49995. if (!function_exists('PHPUnit\Framework\throwException')) {
  49996. function throwException(Throwable $exception): ExceptionStub
  49997. {
  49998. return new ExceptionStub($exception);
  49999. }
  50000. }
  50001. if (!function_exists('PHPUnit\Framework\onConsecutiveCalls')) {
  50002. function onConsecutiveCalls(): ConsecutiveCallsStub
  50003. {
  50004. $arguments = func_get_args();
  50005. return new ConsecutiveCallsStub($arguments);
  50006. }
  50007. }
  50008. <?php
  50009. declare (strict_types=1);
  50010. /*
  50011. * This file is part of PHPUnit.
  50012. *
  50013. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50014. *
  50015. * For the full copyright and license information, please view the LICENSE
  50016. * file that was distributed with this source code.
  50017. */
  50018. namespace PHPUnit\Framework\Attributes;
  50019. use Attribute;
  50020. /**
  50021. * @psalm-immutable
  50022. *
  50023. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50024. */
  50025. #[Attribute(Attribute::TARGET_METHOD)]
  50026. final class After
  50027. {
  50028. }
  50029. <?php
  50030. declare (strict_types=1);
  50031. /*
  50032. * This file is part of PHPUnit.
  50033. *
  50034. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50035. *
  50036. * For the full copyright and license information, please view the LICENSE
  50037. * file that was distributed with this source code.
  50038. */
  50039. namespace PHPUnit\Framework\Attributes;
  50040. use Attribute;
  50041. /**
  50042. * @psalm-immutable
  50043. *
  50044. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50045. */
  50046. #[Attribute(Attribute::TARGET_METHOD)]
  50047. final class AfterClass
  50048. {
  50049. }
  50050. <?php
  50051. declare (strict_types=1);
  50052. /*
  50053. * This file is part of PHPUnit.
  50054. *
  50055. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50056. *
  50057. * For the full copyright and license information, please view the LICENSE
  50058. * file that was distributed with this source code.
  50059. */
  50060. namespace PHPUnit\Framework\Attributes;
  50061. use Attribute;
  50062. /**
  50063. * @psalm-immutable
  50064. *
  50065. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50066. */
  50067. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50068. final class BackupGlobals
  50069. {
  50070. private readonly bool $enabled;
  50071. public function __construct(bool $enabled)
  50072. {
  50073. $this->enabled = $enabled;
  50074. }
  50075. public function enabled(): bool
  50076. {
  50077. return $this->enabled;
  50078. }
  50079. }
  50080. <?php
  50081. declare (strict_types=1);
  50082. /*
  50083. * This file is part of PHPUnit.
  50084. *
  50085. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50086. *
  50087. * For the full copyright and license information, please view the LICENSE
  50088. * file that was distributed with this source code.
  50089. */
  50090. namespace PHPUnit\Framework\Attributes;
  50091. use Attribute;
  50092. /**
  50093. * @psalm-immutable
  50094. *
  50095. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50096. */
  50097. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50098. final class BackupStaticProperties
  50099. {
  50100. private readonly bool $enabled;
  50101. public function __construct(bool $enabled)
  50102. {
  50103. $this->enabled = $enabled;
  50104. }
  50105. public function enabled(): bool
  50106. {
  50107. return $this->enabled;
  50108. }
  50109. }
  50110. <?php
  50111. declare (strict_types=1);
  50112. /*
  50113. * This file is part of PHPUnit.
  50114. *
  50115. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50116. *
  50117. * For the full copyright and license information, please view the LICENSE
  50118. * file that was distributed with this source code.
  50119. */
  50120. namespace PHPUnit\Framework\Attributes;
  50121. use Attribute;
  50122. /**
  50123. * @psalm-immutable
  50124. *
  50125. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50126. */
  50127. #[Attribute(Attribute::TARGET_METHOD)]
  50128. final class Before
  50129. {
  50130. }
  50131. <?php
  50132. declare (strict_types=1);
  50133. /*
  50134. * This file is part of PHPUnit.
  50135. *
  50136. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50137. *
  50138. * For the full copyright and license information, please view the LICENSE
  50139. * file that was distributed with this source code.
  50140. */
  50141. namespace PHPUnit\Framework\Attributes;
  50142. use Attribute;
  50143. /**
  50144. * @psalm-immutable
  50145. *
  50146. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50147. */
  50148. #[Attribute(Attribute::TARGET_METHOD)]
  50149. final class BeforeClass
  50150. {
  50151. }
  50152. <?php
  50153. declare (strict_types=1);
  50154. /*
  50155. * This file is part of PHPUnit.
  50156. *
  50157. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50158. *
  50159. * For the full copyright and license information, please view the LICENSE
  50160. * file that was distributed with this source code.
  50161. */
  50162. namespace PHPUnit\Framework\Attributes;
  50163. use Attribute;
  50164. /**
  50165. * @psalm-immutable
  50166. *
  50167. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50168. *
  50169. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5236
  50170. */
  50171. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50172. final class CodeCoverageIgnore
  50173. {
  50174. }
  50175. <?php
  50176. declare (strict_types=1);
  50177. /*
  50178. * This file is part of PHPUnit.
  50179. *
  50180. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50181. *
  50182. * For the full copyright and license information, please view the LICENSE
  50183. * file that was distributed with this source code.
  50184. */
  50185. namespace PHPUnit\Framework\Attributes;
  50186. use Attribute;
  50187. /**
  50188. * @psalm-immutable
  50189. *
  50190. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50191. */
  50192. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  50193. final class CoversClass
  50194. {
  50195. /**
  50196. * @psalm-var class-string
  50197. */
  50198. private readonly string $className;
  50199. /**
  50200. * @psalm-param class-string $className
  50201. */
  50202. public function __construct(string $className)
  50203. {
  50204. $this->className = $className;
  50205. }
  50206. /**
  50207. * @psalm-return class-string
  50208. */
  50209. public function className(): string
  50210. {
  50211. return $this->className;
  50212. }
  50213. }
  50214. <?php
  50215. declare (strict_types=1);
  50216. /*
  50217. * This file is part of PHPUnit.
  50218. *
  50219. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50220. *
  50221. * For the full copyright and license information, please view the LICENSE
  50222. * file that was distributed with this source code.
  50223. */
  50224. namespace PHPUnit\Framework\Attributes;
  50225. use Attribute;
  50226. /**
  50227. * @psalm-immutable
  50228. *
  50229. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50230. */
  50231. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  50232. final class CoversFunction
  50233. {
  50234. /**
  50235. * @psalm-var non-empty-string
  50236. */
  50237. private readonly string $functionName;
  50238. /**
  50239. * @psalm-param non-empty-string $functionName
  50240. */
  50241. public function __construct(string $functionName)
  50242. {
  50243. $this->functionName = $functionName;
  50244. }
  50245. /**
  50246. * @psalm-return non-empty-string
  50247. */
  50248. public function functionName(): string
  50249. {
  50250. return $this->functionName;
  50251. }
  50252. }
  50253. <?php
  50254. declare (strict_types=1);
  50255. /*
  50256. * This file is part of PHPUnit.
  50257. *
  50258. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50259. *
  50260. * For the full copyright and license information, please view the LICENSE
  50261. * file that was distributed with this source code.
  50262. */
  50263. namespace PHPUnit\Framework\Attributes;
  50264. use Attribute;
  50265. /**
  50266. * @psalm-immutable
  50267. *
  50268. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50269. */
  50270. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50271. final class CoversNothing
  50272. {
  50273. }
  50274. <?php
  50275. declare (strict_types=1);
  50276. /*
  50277. * This file is part of PHPUnit.
  50278. *
  50279. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50280. *
  50281. * For the full copyright and license information, please view the LICENSE
  50282. * file that was distributed with this source code.
  50283. */
  50284. namespace PHPUnit\Framework\Attributes;
  50285. use Attribute;
  50286. /**
  50287. * @psalm-immutable
  50288. *
  50289. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50290. */
  50291. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50292. final class DataProvider
  50293. {
  50294. /**
  50295. * @psalm-var non-empty-string
  50296. */
  50297. private readonly string $methodName;
  50298. /**
  50299. * @psalm-param non-empty-string $methodName
  50300. */
  50301. public function __construct(string $methodName)
  50302. {
  50303. $this->methodName = $methodName;
  50304. }
  50305. /**
  50306. * @psalm-return non-empty-string
  50307. */
  50308. public function methodName(): string
  50309. {
  50310. return $this->methodName;
  50311. }
  50312. }
  50313. <?php
  50314. declare (strict_types=1);
  50315. /*
  50316. * This file is part of PHPUnit.
  50317. *
  50318. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50319. *
  50320. * For the full copyright and license information, please view the LICENSE
  50321. * file that was distributed with this source code.
  50322. */
  50323. namespace PHPUnit\Framework\Attributes;
  50324. use Attribute;
  50325. /**
  50326. * @psalm-immutable
  50327. *
  50328. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50329. */
  50330. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50331. final class DataProviderExternal
  50332. {
  50333. /**
  50334. * @psalm-var class-string
  50335. */
  50336. private readonly string $className;
  50337. /**
  50338. * @psalm-var non-empty-string
  50339. */
  50340. private readonly string $methodName;
  50341. /**
  50342. * @psalm-param class-string $className
  50343. * @psalm-param non-empty-string $methodName
  50344. */
  50345. public function __construct(string $className, string $methodName)
  50346. {
  50347. $this->className = $className;
  50348. $this->methodName = $methodName;
  50349. }
  50350. /**
  50351. * @psalm-return class-string
  50352. */
  50353. public function className(): string
  50354. {
  50355. return $this->className;
  50356. }
  50357. /**
  50358. * @psalm-return non-empty-string
  50359. */
  50360. public function methodName(): string
  50361. {
  50362. return $this->methodName;
  50363. }
  50364. }
  50365. <?php
  50366. declare (strict_types=1);
  50367. /*
  50368. * This file is part of PHPUnit.
  50369. *
  50370. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50371. *
  50372. * For the full copyright and license information, please view the LICENSE
  50373. * file that was distributed with this source code.
  50374. */
  50375. namespace PHPUnit\Framework\Attributes;
  50376. use Attribute;
  50377. /**
  50378. * @psalm-immutable
  50379. *
  50380. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50381. */
  50382. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50383. final class Depends
  50384. {
  50385. /**
  50386. * @psalm-var non-empty-string
  50387. */
  50388. private readonly string $methodName;
  50389. /**
  50390. * @psalm-param non-empty-string $methodName
  50391. */
  50392. public function __construct(string $methodName)
  50393. {
  50394. $this->methodName = $methodName;
  50395. }
  50396. /**
  50397. * @psalm-return non-empty-string
  50398. */
  50399. public function methodName(): string
  50400. {
  50401. return $this->methodName;
  50402. }
  50403. }
  50404. <?php
  50405. declare (strict_types=1);
  50406. /*
  50407. * This file is part of PHPUnit.
  50408. *
  50409. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50410. *
  50411. * For the full copyright and license information, please view the LICENSE
  50412. * file that was distributed with this source code.
  50413. */
  50414. namespace PHPUnit\Framework\Attributes;
  50415. use Attribute;
  50416. /**
  50417. * @psalm-immutable
  50418. *
  50419. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50420. */
  50421. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50422. final class DependsExternal
  50423. {
  50424. /**
  50425. * @psalm-var class-string
  50426. */
  50427. private readonly string $className;
  50428. /**
  50429. * @psalm-var non-empty-string
  50430. */
  50431. private readonly string $methodName;
  50432. /**
  50433. * @psalm-param class-string $className
  50434. * @psalm-param non-empty-string $methodName
  50435. */
  50436. public function __construct(string $className, string $methodName)
  50437. {
  50438. $this->className = $className;
  50439. $this->methodName = $methodName;
  50440. }
  50441. /**
  50442. * @psalm-return class-string
  50443. */
  50444. public function className(): string
  50445. {
  50446. return $this->className;
  50447. }
  50448. /**
  50449. * @psalm-return non-empty-string
  50450. */
  50451. public function methodName(): string
  50452. {
  50453. return $this->methodName;
  50454. }
  50455. }
  50456. <?php
  50457. declare (strict_types=1);
  50458. /*
  50459. * This file is part of PHPUnit.
  50460. *
  50461. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50462. *
  50463. * For the full copyright and license information, please view the LICENSE
  50464. * file that was distributed with this source code.
  50465. */
  50466. namespace PHPUnit\Framework\Attributes;
  50467. use Attribute;
  50468. /**
  50469. * @psalm-immutable
  50470. *
  50471. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50472. */
  50473. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50474. final class DependsExternalUsingDeepClone
  50475. {
  50476. /**
  50477. * @psalm-var class-string
  50478. */
  50479. private readonly string $className;
  50480. /**
  50481. * @psalm-var non-empty-string
  50482. */
  50483. private readonly string $methodName;
  50484. /**
  50485. * @psalm-param class-string $className
  50486. * @psalm-param non-empty-string $methodName
  50487. */
  50488. public function __construct(string $className, string $methodName)
  50489. {
  50490. $this->className = $className;
  50491. $this->methodName = $methodName;
  50492. }
  50493. /**
  50494. * @psalm-return class-string
  50495. */
  50496. public function className(): string
  50497. {
  50498. return $this->className;
  50499. }
  50500. /**
  50501. * @psalm-return non-empty-string
  50502. */
  50503. public function methodName(): string
  50504. {
  50505. return $this->methodName;
  50506. }
  50507. }
  50508. <?php
  50509. declare (strict_types=1);
  50510. /*
  50511. * This file is part of PHPUnit.
  50512. *
  50513. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50514. *
  50515. * For the full copyright and license information, please view the LICENSE
  50516. * file that was distributed with this source code.
  50517. */
  50518. namespace PHPUnit\Framework\Attributes;
  50519. use Attribute;
  50520. /**
  50521. * @psalm-immutable
  50522. *
  50523. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50524. */
  50525. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50526. final class DependsExternalUsingShallowClone
  50527. {
  50528. /**
  50529. * @psalm-var class-string
  50530. */
  50531. private readonly string $className;
  50532. /**
  50533. * @psalm-var non-empty-string
  50534. */
  50535. private readonly string $methodName;
  50536. /**
  50537. * @psalm-param class-string $className
  50538. * @psalm-param non-empty-string $methodName
  50539. */
  50540. public function __construct(string $className, string $methodName)
  50541. {
  50542. $this->className = $className;
  50543. $this->methodName = $methodName;
  50544. }
  50545. /**
  50546. * @psalm-return class-string
  50547. */
  50548. public function className(): string
  50549. {
  50550. return $this->className;
  50551. }
  50552. /**
  50553. * @psalm-return non-empty-string
  50554. */
  50555. public function methodName(): string
  50556. {
  50557. return $this->methodName;
  50558. }
  50559. }
  50560. <?php
  50561. declare (strict_types=1);
  50562. /*
  50563. * This file is part of PHPUnit.
  50564. *
  50565. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50566. *
  50567. * For the full copyright and license information, please view the LICENSE
  50568. * file that was distributed with this source code.
  50569. */
  50570. namespace PHPUnit\Framework\Attributes;
  50571. use Attribute;
  50572. /**
  50573. * @psalm-immutable
  50574. *
  50575. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50576. */
  50577. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50578. final class DependsOnClass
  50579. {
  50580. /**
  50581. * @psalm-var class-string
  50582. */
  50583. private readonly string $className;
  50584. /**
  50585. * @psalm-param class-string $className
  50586. */
  50587. public function __construct(string $className)
  50588. {
  50589. $this->className = $className;
  50590. }
  50591. /**
  50592. * @psalm-return class-string
  50593. */
  50594. public function className(): string
  50595. {
  50596. return $this->className;
  50597. }
  50598. }
  50599. <?php
  50600. declare (strict_types=1);
  50601. /*
  50602. * This file is part of PHPUnit.
  50603. *
  50604. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50605. *
  50606. * For the full copyright and license information, please view the LICENSE
  50607. * file that was distributed with this source code.
  50608. */
  50609. namespace PHPUnit\Framework\Attributes;
  50610. use Attribute;
  50611. /**
  50612. * @psalm-immutable
  50613. *
  50614. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50615. */
  50616. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50617. final class DependsOnClassUsingDeepClone
  50618. {
  50619. /**
  50620. * @psalm-var class-string
  50621. */
  50622. private readonly string $className;
  50623. /**
  50624. * @psalm-param class-string $className
  50625. */
  50626. public function __construct(string $className)
  50627. {
  50628. $this->className = $className;
  50629. }
  50630. /**
  50631. * @psalm-return class-string
  50632. */
  50633. public function className(): string
  50634. {
  50635. return $this->className;
  50636. }
  50637. }
  50638. <?php
  50639. declare (strict_types=1);
  50640. /*
  50641. * This file is part of PHPUnit.
  50642. *
  50643. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50644. *
  50645. * For the full copyright and license information, please view the LICENSE
  50646. * file that was distributed with this source code.
  50647. */
  50648. namespace PHPUnit\Framework\Attributes;
  50649. use Attribute;
  50650. /**
  50651. * @psalm-immutable
  50652. *
  50653. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50654. */
  50655. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50656. final class DependsOnClassUsingShallowClone
  50657. {
  50658. /**
  50659. * @psalm-var class-string
  50660. */
  50661. private readonly string $className;
  50662. /**
  50663. * @psalm-param class-string $className
  50664. */
  50665. public function __construct(string $className)
  50666. {
  50667. $this->className = $className;
  50668. }
  50669. /**
  50670. * @psalm-return class-string
  50671. */
  50672. public function className(): string
  50673. {
  50674. return $this->className;
  50675. }
  50676. }
  50677. <?php
  50678. declare (strict_types=1);
  50679. /*
  50680. * This file is part of PHPUnit.
  50681. *
  50682. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50683. *
  50684. * For the full copyright and license information, please view the LICENSE
  50685. * file that was distributed with this source code.
  50686. */
  50687. namespace PHPUnit\Framework\Attributes;
  50688. use Attribute;
  50689. /**
  50690. * @psalm-immutable
  50691. *
  50692. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50693. */
  50694. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50695. final class DependsUsingDeepClone
  50696. {
  50697. /**
  50698. * @psalm-var non-empty-string
  50699. */
  50700. private readonly string $methodName;
  50701. /**
  50702. * @psalm-param non-empty-string $methodName
  50703. */
  50704. public function __construct(string $methodName)
  50705. {
  50706. $this->methodName = $methodName;
  50707. }
  50708. /**
  50709. * @psalm-return non-empty-string
  50710. */
  50711. public function methodName(): string
  50712. {
  50713. return $this->methodName;
  50714. }
  50715. }
  50716. <?php
  50717. declare (strict_types=1);
  50718. /*
  50719. * This file is part of PHPUnit.
  50720. *
  50721. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50722. *
  50723. * For the full copyright and license information, please view the LICENSE
  50724. * file that was distributed with this source code.
  50725. */
  50726. namespace PHPUnit\Framework\Attributes;
  50727. use Attribute;
  50728. /**
  50729. * @psalm-immutable
  50730. *
  50731. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50732. */
  50733. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50734. final class DependsUsingShallowClone
  50735. {
  50736. /**
  50737. * @psalm-var non-empty-string
  50738. */
  50739. private readonly string $methodName;
  50740. /**
  50741. * @psalm-param non-empty-string $methodName
  50742. */
  50743. public function __construct(string $methodName)
  50744. {
  50745. $this->methodName = $methodName;
  50746. }
  50747. /**
  50748. * @psalm-return non-empty-string
  50749. */
  50750. public function methodName(): string
  50751. {
  50752. return $this->methodName;
  50753. }
  50754. }
  50755. <?php
  50756. declare (strict_types=1);
  50757. /*
  50758. * This file is part of PHPUnit.
  50759. *
  50760. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50761. *
  50762. * For the full copyright and license information, please view the LICENSE
  50763. * file that was distributed with this source code.
  50764. */
  50765. namespace PHPUnit\Framework\Attributes;
  50766. use Attribute;
  50767. /**
  50768. * @psalm-immutable
  50769. *
  50770. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50771. */
  50772. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50773. final class DoesNotPerformAssertions
  50774. {
  50775. }
  50776. <?php
  50777. declare (strict_types=1);
  50778. /*
  50779. * This file is part of PHPUnit.
  50780. *
  50781. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50782. *
  50783. * For the full copyright and license information, please view the LICENSE
  50784. * file that was distributed with this source code.
  50785. */
  50786. namespace PHPUnit\Framework\Attributes;
  50787. use Attribute;
  50788. /**
  50789. * @psalm-immutable
  50790. *
  50791. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50792. */
  50793. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50794. final class ExcludeGlobalVariableFromBackup
  50795. {
  50796. /**
  50797. * @psalm-var non-empty-string
  50798. */
  50799. private readonly string $globalVariableName;
  50800. /**
  50801. * @psalm-param non-empty-string $globalVariableName
  50802. */
  50803. public function __construct(string $globalVariableName)
  50804. {
  50805. $this->globalVariableName = $globalVariableName;
  50806. }
  50807. /**
  50808. * @psalm-return non-empty-string
  50809. */
  50810. public function globalVariableName(): string
  50811. {
  50812. return $this->globalVariableName;
  50813. }
  50814. }
  50815. <?php
  50816. declare (strict_types=1);
  50817. /*
  50818. * This file is part of PHPUnit.
  50819. *
  50820. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50821. *
  50822. * For the full copyright and license information, please view the LICENSE
  50823. * file that was distributed with this source code.
  50824. */
  50825. namespace PHPUnit\Framework\Attributes;
  50826. use Attribute;
  50827. /**
  50828. * @psalm-immutable
  50829. *
  50830. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50831. */
  50832. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50833. final class ExcludeStaticPropertyFromBackup
  50834. {
  50835. /**
  50836. * @psalm-var class-string
  50837. */
  50838. private readonly string $className;
  50839. /**
  50840. * @psalm-var non-empty-string
  50841. */
  50842. private readonly string $propertyName;
  50843. /**
  50844. * @psalm-param class-string $className
  50845. * @psalm-param non-empty-string $propertyName
  50846. */
  50847. public function __construct(string $className, string $propertyName)
  50848. {
  50849. $this->className = $className;
  50850. $this->propertyName = $propertyName;
  50851. }
  50852. /**
  50853. * @psalm-return class-string
  50854. */
  50855. public function className(): string
  50856. {
  50857. return $this->className;
  50858. }
  50859. /**
  50860. * @psalm-return non-empty-string
  50861. */
  50862. public function propertyName(): string
  50863. {
  50864. return $this->propertyName;
  50865. }
  50866. }
  50867. <?php
  50868. declare (strict_types=1);
  50869. /*
  50870. * This file is part of PHPUnit.
  50871. *
  50872. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50873. *
  50874. * For the full copyright and license information, please view the LICENSE
  50875. * file that was distributed with this source code.
  50876. */
  50877. namespace PHPUnit\Framework\Attributes;
  50878. use Attribute;
  50879. /**
  50880. * @psalm-immutable
  50881. *
  50882. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50883. */
  50884. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  50885. final class Group
  50886. {
  50887. /**
  50888. * @psalm-var non-empty-string
  50889. */
  50890. private readonly string $name;
  50891. /**
  50892. * @psalm-param non-empty-string $name
  50893. */
  50894. public function __construct(string $name)
  50895. {
  50896. $this->name = $name;
  50897. }
  50898. /**
  50899. * @psalm-return non-empty-string
  50900. */
  50901. public function name(): string
  50902. {
  50903. return $this->name;
  50904. }
  50905. }
  50906. <?php
  50907. declare (strict_types=1);
  50908. /*
  50909. * This file is part of PHPUnit.
  50910. *
  50911. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50912. *
  50913. * For the full copyright and license information, please view the LICENSE
  50914. * file that was distributed with this source code.
  50915. */
  50916. namespace PHPUnit\Framework\Attributes;
  50917. use Attribute;
  50918. /**
  50919. * @psalm-immutable
  50920. *
  50921. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50922. *
  50923. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  50924. */
  50925. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  50926. final class IgnoreClassForCodeCoverage
  50927. {
  50928. /**
  50929. * @psalm-var class-string
  50930. */
  50931. private readonly string $className;
  50932. /**
  50933. * @psalm-param class-string $className
  50934. */
  50935. public function __construct(string $className)
  50936. {
  50937. $this->className = $className;
  50938. }
  50939. /**
  50940. * @psalm-return class-string
  50941. */
  50942. public function className(): string
  50943. {
  50944. return $this->className;
  50945. }
  50946. }
  50947. <?php
  50948. declare (strict_types=1);
  50949. /*
  50950. * This file is part of PHPUnit.
  50951. *
  50952. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50953. *
  50954. * For the full copyright and license information, please view the LICENSE
  50955. * file that was distributed with this source code.
  50956. */
  50957. namespace PHPUnit\Framework\Attributes;
  50958. use Attribute;
  50959. /**
  50960. * @psalm-immutable
  50961. *
  50962. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50963. */
  50964. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  50965. final class IgnoreDeprecations
  50966. {
  50967. }
  50968. <?php
  50969. declare (strict_types=1);
  50970. /*
  50971. * This file is part of PHPUnit.
  50972. *
  50973. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50974. *
  50975. * For the full copyright and license information, please view the LICENSE
  50976. * file that was distributed with this source code.
  50977. */
  50978. namespace PHPUnit\Framework\Attributes;
  50979. use Attribute;
  50980. /**
  50981. * @psalm-immutable
  50982. *
  50983. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  50984. *
  50985. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  50986. */
  50987. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  50988. final class IgnoreFunctionForCodeCoverage
  50989. {
  50990. /**
  50991. * @psalm-var non-empty-string
  50992. */
  50993. private readonly string $functionName;
  50994. /**
  50995. * @psalm-param non-empty-string $functionName
  50996. */
  50997. public function __construct(string $functionName)
  50998. {
  50999. $this->functionName = $functionName;
  51000. }
  51001. /**
  51002. * @psalm-return non-empty-string
  51003. */
  51004. public function functionName(): string
  51005. {
  51006. return $this->functionName;
  51007. }
  51008. }
  51009. <?php
  51010. declare (strict_types=1);
  51011. /*
  51012. * This file is part of PHPUnit.
  51013. *
  51014. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51015. *
  51016. * For the full copyright and license information, please view the LICENSE
  51017. * file that was distributed with this source code.
  51018. */
  51019. namespace PHPUnit\Framework\Attributes;
  51020. use Attribute;
  51021. /**
  51022. * @psalm-immutable
  51023. *
  51024. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51025. *
  51026. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  51027. */
  51028. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  51029. final class IgnoreMethodForCodeCoverage
  51030. {
  51031. /**
  51032. * @psalm-var class-string
  51033. */
  51034. private readonly string $className;
  51035. /**
  51036. * @psalm-var non-empty-string
  51037. */
  51038. private readonly string $methodName;
  51039. /**
  51040. * @psalm-param class-string $className
  51041. * @psalm-param non-empty-string $methodName
  51042. */
  51043. public function __construct(string $className, string $methodName)
  51044. {
  51045. $this->className = $className;
  51046. $this->methodName = $methodName;
  51047. }
  51048. /**
  51049. * @psalm-return class-string
  51050. */
  51051. public function className(): string
  51052. {
  51053. return $this->className;
  51054. }
  51055. /**
  51056. * @psalm-return non-empty-string
  51057. */
  51058. public function methodName(): string
  51059. {
  51060. return $this->methodName;
  51061. }
  51062. }
  51063. <?php
  51064. declare (strict_types=1);
  51065. /*
  51066. * This file is part of PHPUnit.
  51067. *
  51068. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51069. *
  51070. * For the full copyright and license information, please view the LICENSE
  51071. * file that was distributed with this source code.
  51072. */
  51073. namespace PHPUnit\Framework\Attributes;
  51074. use Attribute;
  51075. /**
  51076. * @psalm-immutable
  51077. *
  51078. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51079. */
  51080. #[Attribute(Attribute::TARGET_CLASS)]
  51081. final class Large
  51082. {
  51083. }
  51084. <?php
  51085. declare (strict_types=1);
  51086. /*
  51087. * This file is part of PHPUnit.
  51088. *
  51089. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51090. *
  51091. * For the full copyright and license information, please view the LICENSE
  51092. * file that was distributed with this source code.
  51093. */
  51094. namespace PHPUnit\Framework\Attributes;
  51095. use Attribute;
  51096. /**
  51097. * @psalm-immutable
  51098. *
  51099. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51100. */
  51101. #[Attribute(Attribute::TARGET_CLASS)]
  51102. final class Medium
  51103. {
  51104. }
  51105. <?php
  51106. declare (strict_types=1);
  51107. /*
  51108. * This file is part of PHPUnit.
  51109. *
  51110. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51111. *
  51112. * For the full copyright and license information, please view the LICENSE
  51113. * file that was distributed with this source code.
  51114. */
  51115. namespace PHPUnit\Framework\Attributes;
  51116. use Attribute;
  51117. /**
  51118. * @psalm-immutable
  51119. *
  51120. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51121. */
  51122. #[Attribute(Attribute::TARGET_METHOD)]
  51123. final class PostCondition
  51124. {
  51125. }
  51126. <?php
  51127. declare (strict_types=1);
  51128. /*
  51129. * This file is part of PHPUnit.
  51130. *
  51131. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51132. *
  51133. * For the full copyright and license information, please view the LICENSE
  51134. * file that was distributed with this source code.
  51135. */
  51136. namespace PHPUnit\Framework\Attributes;
  51137. use Attribute;
  51138. /**
  51139. * @psalm-immutable
  51140. *
  51141. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51142. */
  51143. #[Attribute(Attribute::TARGET_METHOD)]
  51144. final class PreCondition
  51145. {
  51146. }
  51147. <?php
  51148. declare (strict_types=1);
  51149. /*
  51150. * This file is part of PHPUnit.
  51151. *
  51152. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51153. *
  51154. * For the full copyright and license information, please view the LICENSE
  51155. * file that was distributed with this source code.
  51156. */
  51157. namespace PHPUnit\Framework\Attributes;
  51158. use Attribute;
  51159. /**
  51160. * @psalm-immutable
  51161. *
  51162. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51163. */
  51164. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51165. final class PreserveGlobalState
  51166. {
  51167. private readonly bool $enabled;
  51168. public function __construct(bool $enabled)
  51169. {
  51170. $this->enabled = $enabled;
  51171. }
  51172. public function enabled(): bool
  51173. {
  51174. return $this->enabled;
  51175. }
  51176. }
  51177. <?php
  51178. declare (strict_types=1);
  51179. /*
  51180. * This file is part of PHPUnit.
  51181. *
  51182. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51183. *
  51184. * For the full copyright and license information, please view the LICENSE
  51185. * file that was distributed with this source code.
  51186. */
  51187. namespace PHPUnit\Framework\Attributes;
  51188. use Attribute;
  51189. /**
  51190. * @psalm-immutable
  51191. *
  51192. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51193. */
  51194. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51195. final class RequiresFunction
  51196. {
  51197. /**
  51198. * @psalm-var non-empty-string
  51199. */
  51200. private readonly string $functionName;
  51201. /**
  51202. * @psalm-param non-empty-string $functionName
  51203. */
  51204. public function __construct(string $functionName)
  51205. {
  51206. $this->functionName = $functionName;
  51207. }
  51208. /**
  51209. * @psalm-return non-empty-string
  51210. */
  51211. public function functionName(): string
  51212. {
  51213. return $this->functionName;
  51214. }
  51215. }
  51216. <?php
  51217. declare (strict_types=1);
  51218. /*
  51219. * This file is part of PHPUnit.
  51220. *
  51221. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51222. *
  51223. * For the full copyright and license information, please view the LICENSE
  51224. * file that was distributed with this source code.
  51225. */
  51226. namespace PHPUnit\Framework\Attributes;
  51227. use Attribute;
  51228. /**
  51229. * @psalm-immutable
  51230. *
  51231. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51232. */
  51233. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51234. final class RequiresMethod
  51235. {
  51236. /**
  51237. * @psalm-var class-string
  51238. */
  51239. private readonly string $className;
  51240. /**
  51241. * @psalm-var non-empty-string
  51242. */
  51243. private readonly string $methodName;
  51244. /**
  51245. * @psalm-param class-string $className
  51246. * @psalm-param non-empty-string $methodName
  51247. */
  51248. public function __construct(string $className, string $methodName)
  51249. {
  51250. $this->className = $className;
  51251. $this->methodName = $methodName;
  51252. }
  51253. /**
  51254. * @psalm-return class-string
  51255. */
  51256. public function className(): string
  51257. {
  51258. return $this->className;
  51259. }
  51260. /**
  51261. * @psalm-return non-empty-string
  51262. */
  51263. public function methodName(): string
  51264. {
  51265. return $this->methodName;
  51266. }
  51267. }
  51268. <?php
  51269. declare (strict_types=1);
  51270. /*
  51271. * This file is part of PHPUnit.
  51272. *
  51273. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51274. *
  51275. * For the full copyright and license information, please view the LICENSE
  51276. * file that was distributed with this source code.
  51277. */
  51278. namespace PHPUnit\Framework\Attributes;
  51279. use Attribute;
  51280. /**
  51281. * @psalm-immutable
  51282. *
  51283. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51284. */
  51285. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51286. final class RequiresOperatingSystem
  51287. {
  51288. /**
  51289. * @psalm-var non-empty-string
  51290. */
  51291. private readonly string $regularExpression;
  51292. /**
  51293. * @psalm-param non-empty-string $regularExpression
  51294. */
  51295. public function __construct(string $regularExpression)
  51296. {
  51297. $this->regularExpression = $regularExpression;
  51298. }
  51299. /**
  51300. * @psalm-return non-empty-string
  51301. */
  51302. public function regularExpression(): string
  51303. {
  51304. return $this->regularExpression;
  51305. }
  51306. }
  51307. <?php
  51308. declare (strict_types=1);
  51309. /*
  51310. * This file is part of PHPUnit.
  51311. *
  51312. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51313. *
  51314. * For the full copyright and license information, please view the LICENSE
  51315. * file that was distributed with this source code.
  51316. */
  51317. namespace PHPUnit\Framework\Attributes;
  51318. use Attribute;
  51319. /**
  51320. * @psalm-immutable
  51321. *
  51322. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51323. */
  51324. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51325. final class RequiresOperatingSystemFamily
  51326. {
  51327. /**
  51328. * @psalm-var non-empty-string
  51329. */
  51330. private readonly string $operatingSystemFamily;
  51331. /**
  51332. * @psalm-param non-empty-string $operatingSystemFamily
  51333. */
  51334. public function __construct(string $operatingSystemFamily)
  51335. {
  51336. $this->operatingSystemFamily = $operatingSystemFamily;
  51337. }
  51338. /**
  51339. * @psalm-return non-empty-string
  51340. */
  51341. public function operatingSystemFamily(): string
  51342. {
  51343. return $this->operatingSystemFamily;
  51344. }
  51345. }
  51346. <?php
  51347. declare (strict_types=1);
  51348. /*
  51349. * This file is part of PHPUnit.
  51350. *
  51351. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51352. *
  51353. * For the full copyright and license information, please view the LICENSE
  51354. * file that was distributed with this source code.
  51355. */
  51356. namespace PHPUnit\Framework\Attributes;
  51357. use Attribute;
  51358. /**
  51359. * @psalm-immutable
  51360. *
  51361. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51362. */
  51363. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51364. final class RequiresPhp
  51365. {
  51366. /**
  51367. * @psalm-var non-empty-string
  51368. */
  51369. private readonly string $versionRequirement;
  51370. /**
  51371. * @psalm-param non-empty-string $versionRequirement
  51372. */
  51373. public function __construct(string $versionRequirement)
  51374. {
  51375. $this->versionRequirement = $versionRequirement;
  51376. }
  51377. /**
  51378. * @psalm-return non-empty-string
  51379. */
  51380. public function versionRequirement(): string
  51381. {
  51382. return $this->versionRequirement;
  51383. }
  51384. }
  51385. <?php
  51386. declare (strict_types=1);
  51387. /*
  51388. * This file is part of PHPUnit.
  51389. *
  51390. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51391. *
  51392. * For the full copyright and license information, please view the LICENSE
  51393. * file that was distributed with this source code.
  51394. */
  51395. namespace PHPUnit\Framework\Attributes;
  51396. use Attribute;
  51397. /**
  51398. * @psalm-immutable
  51399. *
  51400. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51401. */
  51402. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51403. final class RequiresPhpExtension
  51404. {
  51405. /**
  51406. * @psalm-var non-empty-string
  51407. */
  51408. private readonly string $extension;
  51409. /**
  51410. * @psalm-var null|non-empty-string
  51411. */
  51412. private readonly ?string $versionRequirement;
  51413. /**
  51414. * @psalm-param non-empty-string $extension
  51415. * @psalm-param null|non-empty-string $versionRequirement
  51416. */
  51417. public function __construct(string $extension, ?string $versionRequirement = null)
  51418. {
  51419. $this->extension = $extension;
  51420. $this->versionRequirement = $versionRequirement;
  51421. }
  51422. /**
  51423. * @psalm-return non-empty-string
  51424. */
  51425. public function extension(): string
  51426. {
  51427. return $this->extension;
  51428. }
  51429. /**
  51430. * @psalm-return null|non-empty-string
  51431. */
  51432. public function versionRequirement(): ?string
  51433. {
  51434. return $this->versionRequirement;
  51435. }
  51436. }
  51437. <?php
  51438. declare (strict_types=1);
  51439. /*
  51440. * This file is part of PHPUnit.
  51441. *
  51442. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51443. *
  51444. * For the full copyright and license information, please view the LICENSE
  51445. * file that was distributed with this source code.
  51446. */
  51447. namespace PHPUnit\Framework\Attributes;
  51448. use Attribute;
  51449. /**
  51450. * @psalm-immutable
  51451. *
  51452. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51453. */
  51454. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51455. final class RequiresPhpunit
  51456. {
  51457. /**
  51458. * @psalm-var non-empty-string
  51459. */
  51460. private readonly string $versionRequirement;
  51461. /**
  51462. * @psalm-param non-empty-string $versionRequirement
  51463. */
  51464. public function __construct(string $versionRequirement)
  51465. {
  51466. $this->versionRequirement = $versionRequirement;
  51467. }
  51468. /**
  51469. * @psalm-return non-empty-string
  51470. */
  51471. public function versionRequirement(): string
  51472. {
  51473. return $this->versionRequirement;
  51474. }
  51475. }
  51476. <?php
  51477. declare (strict_types=1);
  51478. /*
  51479. * This file is part of PHPUnit.
  51480. *
  51481. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51482. *
  51483. * For the full copyright and license information, please view the LICENSE
  51484. * file that was distributed with this source code.
  51485. */
  51486. namespace PHPUnit\Framework\Attributes;
  51487. use Attribute;
  51488. /**
  51489. * @psalm-immutable
  51490. *
  51491. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51492. */
  51493. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51494. final class RequiresSetting
  51495. {
  51496. /**
  51497. * @psalm-var non-empty-string
  51498. */
  51499. private readonly string $setting;
  51500. /**
  51501. * @psalm-var non-empty-string
  51502. */
  51503. private readonly string $value;
  51504. /**
  51505. * @psalm-param non-empty-string $setting
  51506. * @psalm-param non-empty-string $value
  51507. */
  51508. public function __construct(string $setting, string $value)
  51509. {
  51510. $this->setting = $setting;
  51511. $this->value = $value;
  51512. }
  51513. /**
  51514. * @psalm-return non-empty-string
  51515. */
  51516. public function setting(): string
  51517. {
  51518. return $this->setting;
  51519. }
  51520. /**
  51521. * @psalm-return non-empty-string
  51522. */
  51523. public function value(): string
  51524. {
  51525. return $this->value;
  51526. }
  51527. }
  51528. <?php
  51529. declare (strict_types=1);
  51530. /*
  51531. * This file is part of PHPUnit.
  51532. *
  51533. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51534. *
  51535. * For the full copyright and license information, please view the LICENSE
  51536. * file that was distributed with this source code.
  51537. */
  51538. namespace PHPUnit\Framework\Attributes;
  51539. use Attribute;
  51540. /**
  51541. * @psalm-immutable
  51542. *
  51543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51544. */
  51545. #[Attribute(Attribute::TARGET_CLASS)]
  51546. final class RunClassInSeparateProcess
  51547. {
  51548. }
  51549. <?php
  51550. declare (strict_types=1);
  51551. /*
  51552. * This file is part of PHPUnit.
  51553. *
  51554. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51555. *
  51556. * For the full copyright and license information, please view the LICENSE
  51557. * file that was distributed with this source code.
  51558. */
  51559. namespace PHPUnit\Framework\Attributes;
  51560. use Attribute;
  51561. /**
  51562. * @psalm-immutable
  51563. *
  51564. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51565. */
  51566. #[Attribute(Attribute::TARGET_METHOD)]
  51567. final class RunInSeparateProcess
  51568. {
  51569. }
  51570. <?php
  51571. declare (strict_types=1);
  51572. /*
  51573. * This file is part of PHPUnit.
  51574. *
  51575. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51576. *
  51577. * For the full copyright and license information, please view the LICENSE
  51578. * file that was distributed with this source code.
  51579. */
  51580. namespace PHPUnit\Framework\Attributes;
  51581. use Attribute;
  51582. /**
  51583. * @psalm-immutable
  51584. *
  51585. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51586. */
  51587. #[Attribute(Attribute::TARGET_CLASS)]
  51588. final class RunTestsInSeparateProcesses
  51589. {
  51590. }
  51591. <?php
  51592. declare (strict_types=1);
  51593. /*
  51594. * This file is part of PHPUnit.
  51595. *
  51596. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51597. *
  51598. * For the full copyright and license information, please view the LICENSE
  51599. * file that was distributed with this source code.
  51600. */
  51601. namespace PHPUnit\Framework\Attributes;
  51602. use Attribute;
  51603. /**
  51604. * @psalm-immutable
  51605. *
  51606. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51607. */
  51608. #[Attribute(Attribute::TARGET_CLASS)]
  51609. final class Small
  51610. {
  51611. }
  51612. <?php
  51613. declare (strict_types=1);
  51614. /*
  51615. * This file is part of PHPUnit.
  51616. *
  51617. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51618. *
  51619. * For the full copyright and license information, please view the LICENSE
  51620. * file that was distributed with this source code.
  51621. */
  51622. namespace PHPUnit\Framework\Attributes;
  51623. use Attribute;
  51624. /**
  51625. * @psalm-immutable
  51626. *
  51627. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51628. */
  51629. #[Attribute(Attribute::TARGET_METHOD)]
  51630. final class Test
  51631. {
  51632. }
  51633. <?php
  51634. declare (strict_types=1);
  51635. /*
  51636. * This file is part of PHPUnit.
  51637. *
  51638. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51639. *
  51640. * For the full copyright and license information, please view the LICENSE
  51641. * file that was distributed with this source code.
  51642. */
  51643. namespace PHPUnit\Framework\Attributes;
  51644. use Attribute;
  51645. /**
  51646. * @psalm-immutable
  51647. *
  51648. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51649. */
  51650. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
  51651. final class TestDox
  51652. {
  51653. /**
  51654. * @psalm-var non-empty-string
  51655. */
  51656. private readonly string $text;
  51657. /**
  51658. * @psalm-param non-empty-string $text
  51659. */
  51660. public function __construct(string $text)
  51661. {
  51662. $this->text = $text;
  51663. }
  51664. /**
  51665. * @psalm-return non-empty-string
  51666. */
  51667. public function text(): string
  51668. {
  51669. return $this->text;
  51670. }
  51671. }
  51672. <?php
  51673. declare (strict_types=1);
  51674. /*
  51675. * This file is part of PHPUnit.
  51676. *
  51677. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51678. *
  51679. * For the full copyright and license information, please view the LICENSE
  51680. * file that was distributed with this source code.
  51681. */
  51682. namespace PHPUnit\Framework\Attributes;
  51683. use Attribute;
  51684. /**
  51685. * @psalm-immutable
  51686. *
  51687. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51688. */
  51689. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51690. final class TestWith
  51691. {
  51692. private readonly array $data;
  51693. public function __construct(array $data)
  51694. {
  51695. $this->data = $data;
  51696. }
  51697. public function data(): array
  51698. {
  51699. return $this->data;
  51700. }
  51701. }
  51702. <?php
  51703. declare (strict_types=1);
  51704. /*
  51705. * This file is part of PHPUnit.
  51706. *
  51707. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51708. *
  51709. * For the full copyright and license information, please view the LICENSE
  51710. * file that was distributed with this source code.
  51711. */
  51712. namespace PHPUnit\Framework\Attributes;
  51713. use Attribute;
  51714. /**
  51715. * @psalm-immutable
  51716. *
  51717. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51718. */
  51719. #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51720. final class TestWithJson
  51721. {
  51722. /**
  51723. * @psalm-var non-empty-string
  51724. */
  51725. private readonly string $json;
  51726. /**
  51727. * @psalm-param non-empty-string $json
  51728. */
  51729. public function __construct(string $json)
  51730. {
  51731. $this->json = $json;
  51732. }
  51733. /**
  51734. * @psalm-return non-empty-string
  51735. */
  51736. public function json(): string
  51737. {
  51738. return $this->json;
  51739. }
  51740. }
  51741. <?php
  51742. declare (strict_types=1);
  51743. /*
  51744. * This file is part of PHPUnit.
  51745. *
  51746. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51747. *
  51748. * For the full copyright and license information, please view the LICENSE
  51749. * file that was distributed with this source code.
  51750. */
  51751. namespace PHPUnit\Framework\Attributes;
  51752. use Attribute;
  51753. /**
  51754. * @psalm-immutable
  51755. *
  51756. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51757. */
  51758. #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
  51759. final class Ticket
  51760. {
  51761. /**
  51762. * @psalm-var non-empty-string
  51763. */
  51764. private readonly string $text;
  51765. /**
  51766. * @psalm-param non-empty-string $text
  51767. */
  51768. public function __construct(string $text)
  51769. {
  51770. $this->text = $text;
  51771. }
  51772. /**
  51773. * @psalm-return non-empty-string
  51774. */
  51775. public function text(): string
  51776. {
  51777. return $this->text;
  51778. }
  51779. }
  51780. <?php
  51781. declare (strict_types=1);
  51782. /*
  51783. * This file is part of PHPUnit.
  51784. *
  51785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51786. *
  51787. * For the full copyright and license information, please view the LICENSE
  51788. * file that was distributed with this source code.
  51789. */
  51790. namespace PHPUnit\Framework\Attributes;
  51791. use Attribute;
  51792. /**
  51793. * @psalm-immutable
  51794. *
  51795. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51796. */
  51797. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  51798. final class UsesClass
  51799. {
  51800. /**
  51801. * @psalm-var class-string
  51802. */
  51803. private readonly string $className;
  51804. /**
  51805. * @psalm-param class-string $className
  51806. */
  51807. public function __construct(string $className)
  51808. {
  51809. $this->className = $className;
  51810. }
  51811. /**
  51812. * @psalm-return class-string
  51813. */
  51814. public function className(): string
  51815. {
  51816. return $this->className;
  51817. }
  51818. }
  51819. <?php
  51820. declare (strict_types=1);
  51821. /*
  51822. * This file is part of PHPUnit.
  51823. *
  51824. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51825. *
  51826. * For the full copyright and license information, please view the LICENSE
  51827. * file that was distributed with this source code.
  51828. */
  51829. namespace PHPUnit\Framework\Attributes;
  51830. use Attribute;
  51831. /**
  51832. * @psalm-immutable
  51833. *
  51834. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51835. */
  51836. #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
  51837. final class UsesFunction
  51838. {
  51839. /**
  51840. * @psalm-var non-empty-string
  51841. */
  51842. private readonly string $functionName;
  51843. /**
  51844. * @psalm-param non-empty-string $functionName
  51845. */
  51846. public function __construct(string $functionName)
  51847. {
  51848. $this->functionName = $functionName;
  51849. }
  51850. /**
  51851. * @psalm-return non-empty-string
  51852. */
  51853. public function functionName(): string
  51854. {
  51855. return $this->functionName;
  51856. }
  51857. }
  51858. <?php
  51859. declare (strict_types=1);
  51860. /*
  51861. * This file is part of PHPUnit.
  51862. *
  51863. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51864. *
  51865. * For the full copyright and license information, please view the LICENSE
  51866. * file that was distributed with this source code.
  51867. */
  51868. namespace PHPUnit\Framework\Attributes;
  51869. use Attribute;
  51870. /**
  51871. * @psalm-immutable
  51872. *
  51873. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51874. */
  51875. #[Attribute(Attribute::TARGET_METHOD)]
  51876. final class WithoutErrorHandler
  51877. {
  51878. }
  51879. <?php
  51880. declare (strict_types=1);
  51881. /*
  51882. * This file is part of PHPUnit.
  51883. *
  51884. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51885. *
  51886. * For the full copyright and license information, please view the LICENSE
  51887. * file that was distributed with this source code.
  51888. */
  51889. namespace PHPUnit\Framework\Constraint;
  51890. /**
  51891. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51892. */
  51893. final class IsFalse extends \PHPUnit\Framework\Constraint\Constraint
  51894. {
  51895. /**
  51896. * Returns a string representation of the constraint.
  51897. */
  51898. public function toString(): string
  51899. {
  51900. return 'is false';
  51901. }
  51902. /**
  51903. * Evaluates the constraint for parameter $other. Returns true if the
  51904. * constraint is met, false otherwise.
  51905. */
  51906. protected function matches(mixed $other): bool
  51907. {
  51908. return $other === \false;
  51909. }
  51910. }
  51911. <?php
  51912. declare (strict_types=1);
  51913. /*
  51914. * This file is part of PHPUnit.
  51915. *
  51916. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51917. *
  51918. * For the full copyright and license information, please view the LICENSE
  51919. * file that was distributed with this source code.
  51920. */
  51921. namespace PHPUnit\Framework\Constraint;
  51922. /**
  51923. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51924. */
  51925. final class IsTrue extends \PHPUnit\Framework\Constraint\Constraint
  51926. {
  51927. /**
  51928. * Returns a string representation of the constraint.
  51929. */
  51930. public function toString(): string
  51931. {
  51932. return 'is true';
  51933. }
  51934. /**
  51935. * Evaluates the constraint for parameter $other. Returns true if the
  51936. * constraint is met, false otherwise.
  51937. */
  51938. protected function matches(mixed $other): bool
  51939. {
  51940. return $other === \true;
  51941. }
  51942. }
  51943. <?php
  51944. declare (strict_types=1);
  51945. /*
  51946. * This file is part of PHPUnit.
  51947. *
  51948. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51949. *
  51950. * For the full copyright and license information, please view the LICENSE
  51951. * file that was distributed with this source code.
  51952. */
  51953. namespace PHPUnit\Framework\Constraint;
  51954. use Closure;
  51955. use ReflectionFunction;
  51956. /**
  51957. * @psalm-template CallbackInput of mixed
  51958. *
  51959. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  51960. */
  51961. final class Callback extends \PHPUnit\Framework\Constraint\Constraint
  51962. {
  51963. /**
  51964. * @psalm-var callable(CallbackInput $input): bool
  51965. */
  51966. private readonly mixed $callback;
  51967. /**
  51968. * @psalm-param callable(CallbackInput $input): bool $callback
  51969. */
  51970. public function __construct(callable $callback)
  51971. {
  51972. $this->callback = $callback;
  51973. }
  51974. /**
  51975. * Returns a string representation of the constraint.
  51976. */
  51977. public function toString(): string
  51978. {
  51979. return 'is accepted by specified callback';
  51980. }
  51981. /**
  51982. * @psalm-suppress ArgumentTypeCoercion
  51983. */
  51984. public function isVariadic(): bool
  51985. {
  51986. foreach ((new ReflectionFunction(Closure::fromCallable($this->callback)))->getParameters() as $parameter) {
  51987. if ($parameter->isVariadic()) {
  51988. return \true;
  51989. }
  51990. }
  51991. return \false;
  51992. }
  51993. /**
  51994. * Evaluates the constraint for parameter $value. Returns true if the
  51995. * constraint is met, false otherwise.
  51996. *
  51997. * @psalm-param CallbackInput $other
  51998. *
  51999. * @psalm-suppress InvalidArgument
  52000. */
  52001. protected function matches(mixed $other): bool
  52002. {
  52003. if ($this->isVariadic()) {
  52004. return ($this->callback)(...$other);
  52005. }
  52006. return ($this->callback)($other);
  52007. }
  52008. }
  52009. <?php
  52010. declare (strict_types=1);
  52011. /*
  52012. * This file is part of PHPUnit.
  52013. *
  52014. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52015. *
  52016. * For the full copyright and license information, please view the LICENSE
  52017. * file that was distributed with this source code.
  52018. */
  52019. namespace PHPUnit\Framework\Constraint;
  52020. use function count;
  52021. use function is_countable;
  52022. use function iterator_count;
  52023. use function sprintf;
  52024. use EmptyIterator;
  52025. use Generator;
  52026. use Iterator;
  52027. use IteratorAggregate;
  52028. use PHPUnit\Framework\Exception;
  52029. use PHPUnit\Framework\GeneratorNotSupportedException;
  52030. use Traversable;
  52031. /**
  52032. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52033. */
  52034. class Count extends \PHPUnit\Framework\Constraint\Constraint
  52035. {
  52036. private readonly int $expectedCount;
  52037. public function __construct(int $expected)
  52038. {
  52039. $this->expectedCount = $expected;
  52040. }
  52041. public function toString(): string
  52042. {
  52043. return sprintf('count matches %d', $this->expectedCount);
  52044. }
  52045. /**
  52046. * Evaluates the constraint for parameter $other. Returns true if the
  52047. * constraint is met, false otherwise.
  52048. *
  52049. * @throws Exception
  52050. */
  52051. protected function matches(mixed $other): bool
  52052. {
  52053. return $this->expectedCount === $this->getCountOf($other);
  52054. }
  52055. /**
  52056. * @throws Exception
  52057. */
  52058. protected function getCountOf(mixed $other): ?int
  52059. {
  52060. if (is_countable($other)) {
  52061. return count($other);
  52062. }
  52063. if ($other instanceof EmptyIterator) {
  52064. return 0;
  52065. }
  52066. if ($other instanceof Traversable) {
  52067. while ($other instanceof IteratorAggregate) {
  52068. try {
  52069. $other = $other->getIterator();
  52070. } catch (\Exception $e) {
  52071. throw new Exception($e->getMessage(), $e->getCode(), $e);
  52072. }
  52073. }
  52074. $iterator = $other;
  52075. if ($iterator instanceof Generator) {
  52076. throw new GeneratorNotSupportedException();
  52077. }
  52078. if (!$iterator instanceof Iterator) {
  52079. return iterator_count($iterator);
  52080. }
  52081. $key = $iterator->key();
  52082. $count = iterator_count($iterator);
  52083. // Manually rewind $iterator to previous key, since iterator_count
  52084. // moves pointer.
  52085. if ($key !== null) {
  52086. $iterator->rewind();
  52087. while ($iterator->valid() && $key !== $iterator->key()) {
  52088. $iterator->next();
  52089. }
  52090. }
  52091. return $count;
  52092. }
  52093. return null;
  52094. }
  52095. /**
  52096. * Returns the description of the failure.
  52097. *
  52098. * The beginning of failure messages is "Failed asserting that" in most
  52099. * cases. This method should return the second part of that sentence.
  52100. *
  52101. * @throws Exception
  52102. */
  52103. protected function failureDescription(mixed $other): string
  52104. {
  52105. return sprintf('actual size %d matches expected size %d', (int) $this->getCountOf($other), $this->expectedCount);
  52106. }
  52107. }
  52108. <?php
  52109. declare (strict_types=1);
  52110. /*
  52111. * This file is part of PHPUnit.
  52112. *
  52113. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52114. *
  52115. * For the full copyright and license information, please view the LICENSE
  52116. * file that was distributed with this source code.
  52117. */
  52118. namespace PHPUnit\Framework\Constraint;
  52119. use PHPUnit\Util\Exporter;
  52120. /**
  52121. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52122. */
  52123. final class GreaterThan extends \PHPUnit\Framework\Constraint\Constraint
  52124. {
  52125. private readonly mixed $value;
  52126. public function __construct(mixed $value)
  52127. {
  52128. $this->value = $value;
  52129. }
  52130. /**
  52131. * Returns a string representation of the constraint.
  52132. */
  52133. public function toString(bool $exportObjects = \false): string
  52134. {
  52135. return 'is greater than ' . Exporter::export($this->value, $exportObjects);
  52136. }
  52137. /**
  52138. * Evaluates the constraint for parameter $other. Returns true if the
  52139. * constraint is met, false otherwise.
  52140. */
  52141. protected function matches(mixed $other): bool
  52142. {
  52143. return $this->value < $other;
  52144. }
  52145. }
  52146. <?php
  52147. declare (strict_types=1);
  52148. /*
  52149. * This file is part of PHPUnit.
  52150. *
  52151. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52152. *
  52153. * For the full copyright and license information, please view the LICENSE
  52154. * file that was distributed with this source code.
  52155. */
  52156. namespace PHPUnit\Framework\Constraint;
  52157. use function count;
  52158. use function gettype;
  52159. use function sprintf;
  52160. use function str_starts_with;
  52161. use Countable;
  52162. use EmptyIterator;
  52163. /**
  52164. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52165. */
  52166. final class IsEmpty extends \PHPUnit\Framework\Constraint\Constraint
  52167. {
  52168. /**
  52169. * Returns a string representation of the constraint.
  52170. */
  52171. public function toString(): string
  52172. {
  52173. return 'is empty';
  52174. }
  52175. /**
  52176. * Evaluates the constraint for parameter $other. Returns true if the
  52177. * constraint is met, false otherwise.
  52178. */
  52179. protected function matches(mixed $other): bool
  52180. {
  52181. if ($other instanceof EmptyIterator) {
  52182. return \true;
  52183. }
  52184. if ($other instanceof Countable) {
  52185. return count($other) === 0;
  52186. }
  52187. return empty($other);
  52188. }
  52189. /**
  52190. * Returns the description of the failure.
  52191. *
  52192. * The beginning of failure messages is "Failed asserting that" in most
  52193. * cases. This method should return the second part of that sentence.
  52194. */
  52195. protected function failureDescription(mixed $other): string
  52196. {
  52197. $type = gettype($other);
  52198. return sprintf('%s %s %s', str_starts_with($type, 'a') || str_starts_with($type, 'o') ? 'an' : 'a', $type, $this->toString(\true));
  52199. }
  52200. }
  52201. <?php
  52202. declare (strict_types=1);
  52203. /*
  52204. * This file is part of PHPUnit.
  52205. *
  52206. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52207. *
  52208. * For the full copyright and license information, please view the LICENSE
  52209. * file that was distributed with this source code.
  52210. */
  52211. namespace PHPUnit\Framework\Constraint;
  52212. use PHPUnit\Util\Exporter;
  52213. /**
  52214. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52215. */
  52216. final class LessThan extends \PHPUnit\Framework\Constraint\Constraint
  52217. {
  52218. private readonly mixed $value;
  52219. public function __construct(mixed $value)
  52220. {
  52221. $this->value = $value;
  52222. }
  52223. /**
  52224. * Returns a string representation of the constraint.
  52225. */
  52226. public function toString(bool $exportObjects = \false): string
  52227. {
  52228. return 'is less than ' . Exporter::export($this->value, $exportObjects);
  52229. }
  52230. /**
  52231. * Evaluates the constraint for parameter $other. Returns true if the
  52232. * constraint is met, false otherwise.
  52233. */
  52234. protected function matches(mixed $other): bool
  52235. {
  52236. return $this->value > $other;
  52237. }
  52238. }
  52239. <?php
  52240. declare (strict_types=1);
  52241. /*
  52242. * This file is part of PHPUnit.
  52243. *
  52244. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52245. *
  52246. * For the full copyright and license information, please view the LICENSE
  52247. * file that was distributed with this source code.
  52248. */
  52249. namespace PHPUnit\Framework\Constraint;
  52250. use Countable;
  52251. use PHPUnit\Framework\Exception;
  52252. /**
  52253. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52254. */
  52255. final class SameSize extends \PHPUnit\Framework\Constraint\Count
  52256. {
  52257. /**
  52258. * @psalm-param Countable|iterable $expected
  52259. *
  52260. * @throws Exception
  52261. */
  52262. public function __construct($expected)
  52263. {
  52264. parent::__construct((int) $this->getCountOf($expected));
  52265. }
  52266. }
  52267. <?php
  52268. declare (strict_types=1);
  52269. /*
  52270. * This file is part of PHPUnit.
  52271. *
  52272. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52273. *
  52274. * For the full copyright and license information, please view the LICENSE
  52275. * file that was distributed with this source code.
  52276. */
  52277. namespace PHPUnit\Framework\Constraint;
  52278. use function gettype;
  52279. use function sprintf;
  52280. use function strtolower;
  52281. use Countable;
  52282. use PHPUnit\Framework\ExpectationFailedException;
  52283. use PHPUnit\Framework\SelfDescribing;
  52284. use PHPUnit\Util\Exporter;
  52285. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  52286. /**
  52287. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52288. */
  52289. abstract class Constraint implements Countable, SelfDescribing
  52290. {
  52291. /**
  52292. * Evaluates the constraint for parameter $other.
  52293. *
  52294. * If $returnResult is set to false (the default), an exception is thrown
  52295. * in case of a failure. null is returned otherwise.
  52296. *
  52297. * If $returnResult is true, the result of the evaluation is returned as
  52298. * a boolean value instead: true in case of success, false in case of a
  52299. * failure.
  52300. *
  52301. * @throws ExpectationFailedException
  52302. */
  52303. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  52304. {
  52305. $success = \false;
  52306. if ($this->matches($other)) {
  52307. $success = \true;
  52308. }
  52309. if ($returnResult) {
  52310. return $success;
  52311. }
  52312. if (!$success) {
  52313. $this->fail($other, $description);
  52314. }
  52315. return null;
  52316. }
  52317. /**
  52318. * Counts the number of constraint elements.
  52319. */
  52320. public function count(): int
  52321. {
  52322. return 1;
  52323. }
  52324. /**
  52325. * @deprecated
  52326. */
  52327. protected function exporter(): \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter
  52328. {
  52329. return new \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter();
  52330. }
  52331. /**
  52332. * Evaluates the constraint for parameter $other. Returns true if the
  52333. * constraint is met, false otherwise.
  52334. *
  52335. * This method can be overridden to implement the evaluation algorithm.
  52336. */
  52337. protected function matches(mixed $other): bool
  52338. {
  52339. return \false;
  52340. }
  52341. /**
  52342. * Throws an exception for the given compared value and test description.
  52343. *
  52344. * @throws ExpectationFailedException
  52345. */
  52346. protected function fail(mixed $other, string $description, ?ComparisonFailure $comparisonFailure = null): never
  52347. {
  52348. $failureDescription = sprintf('Failed asserting that %s.', $this->failureDescription($other));
  52349. $additionalFailureDescription = $this->additionalFailureDescription($other);
  52350. if ($additionalFailureDescription) {
  52351. $failureDescription .= "\n" . $additionalFailureDescription;
  52352. }
  52353. if (!empty($description)) {
  52354. $failureDescription = $description . "\n" . $failureDescription;
  52355. }
  52356. throw new ExpectationFailedException($failureDescription, $comparisonFailure);
  52357. }
  52358. /**
  52359. * Return additional failure description where needed.
  52360. *
  52361. * The function can be overridden to provide additional failure
  52362. * information like a diff
  52363. */
  52364. protected function additionalFailureDescription(mixed $other): string
  52365. {
  52366. return '';
  52367. }
  52368. /**
  52369. * Returns the description of the failure.
  52370. *
  52371. * The beginning of failure messages is "Failed asserting that" in most
  52372. * cases. This method should return the second part of that sentence.
  52373. *
  52374. * To provide additional failure information additionalFailureDescription
  52375. * can be used.
  52376. */
  52377. protected function failureDescription(mixed $other): string
  52378. {
  52379. return Exporter::export($other, \true) . ' ' . $this->toString(\true);
  52380. }
  52381. /**
  52382. * Returns a custom string representation of the constraint object when it
  52383. * appears in context of an $operator expression.
  52384. *
  52385. * The purpose of this method is to provide meaningful descriptive string
  52386. * in context of operators such as LogicalNot. Native PHPUnit constraints
  52387. * are supported out of the box by LogicalNot, but externally developed
  52388. * ones had no way to provide correct strings in this context.
  52389. *
  52390. * The method shall return empty string, when it does not handle
  52391. * customization by itself.
  52392. */
  52393. protected function toStringInContext(\PHPUnit\Framework\Constraint\Operator $operator, mixed $role): string
  52394. {
  52395. return '';
  52396. }
  52397. /**
  52398. * Returns the description of the failure when this constraint appears in
  52399. * context of an $operator expression.
  52400. *
  52401. * The purpose of this method is to provide meaningful failure description
  52402. * in context of operators such as LogicalNot. Native PHPUnit constraints
  52403. * are supported out of the box by LogicalNot, but externally developed
  52404. * ones had no way to provide correct messages in this context.
  52405. *
  52406. * The method shall return empty string, when it does not handle
  52407. * customization by itself.
  52408. */
  52409. protected function failureDescriptionInContext(\PHPUnit\Framework\Constraint\Operator $operator, mixed $role, mixed $other): string
  52410. {
  52411. $string = $this->toStringInContext($operator, $role);
  52412. if ($string === '') {
  52413. return '';
  52414. }
  52415. return Exporter::export($other, \true) . ' ' . $string;
  52416. }
  52417. /**
  52418. * Reduces the sub-expression starting at $this by skipping degenerate
  52419. * sub-expression and returns first descendant constraint that starts
  52420. * a non-reducible sub-expression.
  52421. *
  52422. * Returns $this for terminal constraints and for operators that start
  52423. * non-reducible sub-expression, or the nearest descendant of $this that
  52424. * starts a non-reducible sub-expression.
  52425. *
  52426. * A constraint expression may be modelled as a tree with non-terminal
  52427. * nodes (operators) and terminal nodes. For example:
  52428. *
  52429. * LogicalOr (operator, non-terminal)
  52430. * + LogicalAnd (operator, non-terminal)
  52431. * | + IsType('int') (terminal)
  52432. * | + GreaterThan(10) (terminal)
  52433. * + LogicalNot (operator, non-terminal)
  52434. * + IsType('array') (terminal)
  52435. *
  52436. * A degenerate sub-expression is a part of the tree, that effectively does
  52437. * not contribute to the evaluation of the expression it appears in. An example
  52438. * of degenerate sub-expression is a BinaryOperator constructed with single
  52439. * operand or nested BinaryOperators, each with single operand. An
  52440. * expression involving a degenerate sub-expression is equivalent to a
  52441. * reduced expression with the degenerate sub-expression removed, for example
  52442. *
  52443. * LogicalAnd (operator)
  52444. * + LogicalOr (degenerate operator)
  52445. * | + LogicalAnd (degenerate operator)
  52446. * | + IsType('int') (terminal)
  52447. * + GreaterThan(10) (terminal)
  52448. *
  52449. * is equivalent to
  52450. *
  52451. * LogicalAnd (operator)
  52452. * + IsType('int') (terminal)
  52453. * + GreaterThan(10) (terminal)
  52454. *
  52455. * because the subexpression
  52456. *
  52457. * + LogicalOr
  52458. * + LogicalAnd
  52459. * + -
  52460. *
  52461. * is degenerate. Calling reduce() on the LogicalOr object above, as well
  52462. * as on LogicalAnd, shall return the IsType('int') instance.
  52463. *
  52464. * Other specific reductions can be implemented, for example cascade of
  52465. * LogicalNot operators
  52466. *
  52467. * + LogicalNot
  52468. * + LogicalNot
  52469. * +LogicalNot
  52470. * + IsTrue
  52471. *
  52472. * can be reduced to
  52473. *
  52474. * LogicalNot
  52475. * + IsTrue
  52476. */
  52477. protected function reduce(): self
  52478. {
  52479. return $this;
  52480. }
  52481. /**
  52482. * @psalm-return non-empty-string
  52483. */
  52484. protected function valueToTypeStringFragment(mixed $value): string
  52485. {
  52486. $type = strtolower(gettype($value));
  52487. if ($type === 'double') {
  52488. $type = 'float';
  52489. }
  52490. if ($type === 'resource (closed)') {
  52491. $type = 'closed resource';
  52492. }
  52493. return match ($type) {
  52494. 'array', 'integer', 'object' => 'an ' . $type . ' ',
  52495. 'boolean', 'closed resource', 'float', 'resource', 'string' => 'a ' . $type . ' ',
  52496. 'null' => 'null ',
  52497. default => 'a value of ' . $type . ' ',
  52498. };
  52499. }
  52500. }
  52501. <?php
  52502. declare (strict_types=1);
  52503. /*
  52504. * This file is part of PHPUnit.
  52505. *
  52506. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52507. *
  52508. * For the full copyright and license information, please view the LICENSE
  52509. * file that was distributed with this source code.
  52510. */
  52511. namespace PHPUnit\Framework\Constraint;
  52512. use function is_string;
  52513. use function sprintf;
  52514. use function str_contains;
  52515. use function trim;
  52516. use PHPUnit\Framework\ExpectationFailedException;
  52517. use PHPUnit\Util\Exporter;
  52518. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  52519. use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
  52520. /**
  52521. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52522. */
  52523. final class IsEqual extends \PHPUnit\Framework\Constraint\Constraint
  52524. {
  52525. private readonly mixed $value;
  52526. private readonly float $delta;
  52527. private readonly bool $canonicalize;
  52528. private readonly bool $ignoreCase;
  52529. public function __construct(mixed $value, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false)
  52530. {
  52531. $this->value = $value;
  52532. $this->delta = $delta;
  52533. $this->canonicalize = $canonicalize;
  52534. $this->ignoreCase = $ignoreCase;
  52535. }
  52536. /**
  52537. * Evaluates the constraint for parameter $other.
  52538. *
  52539. * If $returnResult is set to false (the default), an exception is thrown
  52540. * in case of a failure. null is returned otherwise.
  52541. *
  52542. * If $returnResult is true, the result of the evaluation is returned as
  52543. * a boolean value instead: true in case of success, false in case of a
  52544. * failure.
  52545. *
  52546. * @throws ExpectationFailedException
  52547. */
  52548. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  52549. {
  52550. // If $this->value and $other are identical, they are also equal.
  52551. // This is the most common path and will allow us to skip
  52552. // initialization of all the comparators.
  52553. if ($this->value === $other) {
  52554. return \true;
  52555. }
  52556. $comparatorFactory = ComparatorFactory::getInstance();
  52557. try {
  52558. $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
  52559. $comparator->assertEquals($this->value, $other, $this->delta, $this->canonicalize, $this->ignoreCase);
  52560. } catch (ComparisonFailure $f) {
  52561. if ($returnResult) {
  52562. return \false;
  52563. }
  52564. throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
  52565. }
  52566. return \true;
  52567. }
  52568. /**
  52569. * Returns a string representation of the constraint.
  52570. */
  52571. public function toString(bool $exportObjects = \false): string
  52572. {
  52573. $delta = '';
  52574. if (is_string($this->value)) {
  52575. if (str_contains($this->value, "\n")) {
  52576. return 'is equal to <text>';
  52577. }
  52578. return sprintf("is equal to '%s'", $this->value);
  52579. }
  52580. if ($this->delta != 0) {
  52581. $delta = sprintf(' with delta <%F>', $this->delta);
  52582. }
  52583. return sprintf('is equal to %s%s', Exporter::export($this->value, $exportObjects), $delta);
  52584. }
  52585. }
  52586. <?php
  52587. declare (strict_types=1);
  52588. /*
  52589. * This file is part of PHPUnit.
  52590. *
  52591. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52592. *
  52593. * For the full copyright and license information, please view the LICENSE
  52594. * file that was distributed with this source code.
  52595. */
  52596. namespace PHPUnit\Framework\Constraint;
  52597. use function is_string;
  52598. use function sprintf;
  52599. use function str_contains;
  52600. use function trim;
  52601. use PHPUnit\Framework\ExpectationFailedException;
  52602. use PHPUnit\Util\Exporter;
  52603. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  52604. use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
  52605. /**
  52606. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52607. */
  52608. final class IsEqualCanonicalizing extends \PHPUnit\Framework\Constraint\Constraint
  52609. {
  52610. private readonly mixed $value;
  52611. public function __construct(mixed $value)
  52612. {
  52613. $this->value = $value;
  52614. }
  52615. /**
  52616. * Evaluates the constraint for parameter $other.
  52617. *
  52618. * If $returnResult is set to false (the default), an exception is thrown
  52619. * in case of a failure. null is returned otherwise.
  52620. *
  52621. * If $returnResult is true, the result of the evaluation is returned as
  52622. * a boolean value instead: true in case of success, false in case of a
  52623. * failure.
  52624. *
  52625. * @throws ExpectationFailedException
  52626. */
  52627. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  52628. {
  52629. // If $this->value and $other are identical, they are also equal.
  52630. // This is the most common path and will allow us to skip
  52631. // initialization of all the comparators.
  52632. if ($this->value === $other) {
  52633. return \true;
  52634. }
  52635. $comparatorFactory = ComparatorFactory::getInstance();
  52636. try {
  52637. $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
  52638. $comparator->assertEquals($this->value, $other, 0.0, \true);
  52639. } catch (ComparisonFailure $f) {
  52640. if ($returnResult) {
  52641. return \false;
  52642. }
  52643. throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
  52644. }
  52645. return \true;
  52646. }
  52647. /**
  52648. * Returns a string representation of the constraint.
  52649. */
  52650. public function toString(bool $exportObjects = \false): string
  52651. {
  52652. if (is_string($this->value)) {
  52653. if (str_contains($this->value, "\n")) {
  52654. return 'is equal to <text>';
  52655. }
  52656. return sprintf("is equal to '%s'", $this->value);
  52657. }
  52658. return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects));
  52659. }
  52660. }
  52661. <?php
  52662. declare (strict_types=1);
  52663. /*
  52664. * This file is part of PHPUnit.
  52665. *
  52666. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52667. *
  52668. * For the full copyright and license information, please view the LICENSE
  52669. * file that was distributed with this source code.
  52670. */
  52671. namespace PHPUnit\Framework\Constraint;
  52672. use function is_string;
  52673. use function sprintf;
  52674. use function str_contains;
  52675. use function trim;
  52676. use PHPUnit\Framework\ExpectationFailedException;
  52677. use PHPUnit\Util\Exporter;
  52678. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  52679. use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
  52680. /**
  52681. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52682. */
  52683. final class IsEqualIgnoringCase extends \PHPUnit\Framework\Constraint\Constraint
  52684. {
  52685. private readonly mixed $value;
  52686. public function __construct(mixed $value)
  52687. {
  52688. $this->value = $value;
  52689. }
  52690. /**
  52691. * Evaluates the constraint for parameter $other.
  52692. *
  52693. * If $returnResult is set to false (the default), an exception is thrown
  52694. * in case of a failure. null is returned otherwise.
  52695. *
  52696. * If $returnResult is true, the result of the evaluation is returned as
  52697. * a boolean value instead: true in case of success, false in case of a
  52698. * failure.
  52699. *
  52700. * @throws ExpectationFailedException
  52701. */
  52702. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  52703. {
  52704. // If $this->value and $other are identical, they are also equal.
  52705. // This is the most common path and will allow us to skip
  52706. // initialization of all the comparators.
  52707. if ($this->value === $other) {
  52708. return \true;
  52709. }
  52710. $comparatorFactory = ComparatorFactory::getInstance();
  52711. try {
  52712. $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
  52713. $comparator->assertEquals($this->value, $other, 0.0, \false, \true);
  52714. } catch (ComparisonFailure $f) {
  52715. if ($returnResult) {
  52716. return \false;
  52717. }
  52718. throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
  52719. }
  52720. return \true;
  52721. }
  52722. /**
  52723. * Returns a string representation of the constraint.
  52724. */
  52725. public function toString(bool $exportObjects = \false): string
  52726. {
  52727. if (is_string($this->value)) {
  52728. if (str_contains($this->value, "\n")) {
  52729. return 'is equal to <text>';
  52730. }
  52731. return sprintf("is equal to '%s'", $this->value);
  52732. }
  52733. return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects));
  52734. }
  52735. }
  52736. <?php
  52737. declare (strict_types=1);
  52738. /*
  52739. * This file is part of PHPUnit.
  52740. *
  52741. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52742. *
  52743. * For the full copyright and license information, please view the LICENSE
  52744. * file that was distributed with this source code.
  52745. */
  52746. namespace PHPUnit\Framework\Constraint;
  52747. use function sprintf;
  52748. use function trim;
  52749. use PHPUnit\Framework\ExpectationFailedException;
  52750. use PHPUnit\Util\Exporter;
  52751. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  52752. use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
  52753. /**
  52754. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52755. */
  52756. final class IsEqualWithDelta extends \PHPUnit\Framework\Constraint\Constraint
  52757. {
  52758. private readonly mixed $value;
  52759. private readonly float $delta;
  52760. public function __construct(mixed $value, float $delta)
  52761. {
  52762. $this->value = $value;
  52763. $this->delta = $delta;
  52764. }
  52765. /**
  52766. * Evaluates the constraint for parameter $other.
  52767. *
  52768. * If $returnResult is set to false (the default), an exception is thrown
  52769. * in case of a failure. null is returned otherwise.
  52770. *
  52771. * If $returnResult is true, the result of the evaluation is returned as
  52772. * a boolean value instead: true in case of success, false in case of a
  52773. * failure.
  52774. *
  52775. * @throws ExpectationFailedException
  52776. */
  52777. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  52778. {
  52779. // If $this->value and $other are identical, they are also equal.
  52780. // This is the most common path and will allow us to skip
  52781. // initialization of all the comparators.
  52782. if ($this->value === $other) {
  52783. return \true;
  52784. }
  52785. $comparatorFactory = ComparatorFactory::getInstance();
  52786. try {
  52787. $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
  52788. $comparator->assertEquals($this->value, $other, $this->delta);
  52789. } catch (ComparisonFailure $f) {
  52790. if ($returnResult) {
  52791. return \false;
  52792. }
  52793. throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
  52794. }
  52795. return \true;
  52796. }
  52797. /**
  52798. * Returns a string representation of the constraint.
  52799. */
  52800. public function toString(bool $exportObjects = \false): string
  52801. {
  52802. return sprintf('is equal to %s with delta <%F>', Exporter::export($this->value, $exportObjects), $this->delta);
  52803. }
  52804. }
  52805. <?php
  52806. declare (strict_types=1);
  52807. /*
  52808. * This file is part of PHPUnit.
  52809. *
  52810. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52811. *
  52812. * For the full copyright and license information, please view the LICENSE
  52813. * file that was distributed with this source code.
  52814. */
  52815. namespace PHPUnit\Framework\Constraint;
  52816. use function sprintf;
  52817. use PHPUnit\Util\Filter;
  52818. use Throwable;
  52819. /**
  52820. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52821. *
  52822. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  52823. */
  52824. final class Exception extends \PHPUnit\Framework\Constraint\Constraint
  52825. {
  52826. private readonly string $className;
  52827. public function __construct(string $className)
  52828. {
  52829. $this->className = $className;
  52830. }
  52831. /**
  52832. * Returns a string representation of the constraint.
  52833. */
  52834. public function toString(): string
  52835. {
  52836. return sprintf('exception of type "%s"', $this->className);
  52837. }
  52838. /**
  52839. * Evaluates the constraint for parameter $other. Returns true if the
  52840. * constraint is met, false otherwise.
  52841. */
  52842. protected function matches(mixed $other): bool
  52843. {
  52844. return $other instanceof $this->className;
  52845. }
  52846. /**
  52847. * Returns the description of the failure.
  52848. *
  52849. * The beginning of failure messages is "Failed asserting that" in most
  52850. * cases. This method should return the second part of that sentence.
  52851. *
  52852. * @throws \PHPUnit\Framework\Exception
  52853. */
  52854. protected function failureDescription(mixed $other): string
  52855. {
  52856. if ($other === null) {
  52857. return sprintf('exception of type "%s" is thrown', $this->className);
  52858. }
  52859. $message = '';
  52860. if ($other instanceof Throwable) {
  52861. $message = '. Message was: "' . $other->getMessage() . '" at' . "\n" . Filter::getFilteredStacktrace($other);
  52862. }
  52863. return sprintf('exception of type "%s" matches expected exception "%s"%s', $other::class, $this->className, $message);
  52864. }
  52865. }
  52866. <?php
  52867. declare (strict_types=1);
  52868. /*
  52869. * This file is part of PHPUnit.
  52870. *
  52871. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52872. *
  52873. * For the full copyright and license information, please view the LICENSE
  52874. * file that was distributed with this source code.
  52875. */
  52876. namespace PHPUnit\Framework\Constraint;
  52877. use function sprintf;
  52878. use PHPUnit\Util\Exporter;
  52879. /**
  52880. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52881. *
  52882. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  52883. */
  52884. final class ExceptionCode extends \PHPUnit\Framework\Constraint\Constraint
  52885. {
  52886. private readonly int|string $expectedCode;
  52887. public function __construct(int|string $expected)
  52888. {
  52889. $this->expectedCode = $expected;
  52890. }
  52891. public function toString(): string
  52892. {
  52893. return 'exception code is ' . $this->expectedCode;
  52894. }
  52895. /**
  52896. * Evaluates the constraint for parameter $other. Returns true if the
  52897. * constraint is met, false otherwise.
  52898. */
  52899. protected function matches(mixed $other): bool
  52900. {
  52901. return (string) $other === (string) $this->expectedCode;
  52902. }
  52903. /**
  52904. * Returns the description of the failure.
  52905. *
  52906. * The beginning of failure messages is "Failed asserting that" in most
  52907. * cases. This method should return the second part of that sentence.
  52908. */
  52909. protected function failureDescription(mixed $other): string
  52910. {
  52911. return sprintf('%s is equal to expected exception code %s', Exporter::export($other, \true), Exporter::export($this->expectedCode, \true));
  52912. }
  52913. }
  52914. <?php
  52915. declare (strict_types=1);
  52916. /*
  52917. * This file is part of PHPUnit.
  52918. *
  52919. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52920. *
  52921. * For the full copyright and license information, please view the LICENSE
  52922. * file that was distributed with this source code.
  52923. */
  52924. namespace PHPUnit\Framework\Constraint;
  52925. use function sprintf;
  52926. use function str_contains;
  52927. use PHPUnit\Util\Exporter;
  52928. /**
  52929. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52930. *
  52931. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  52932. */
  52933. final class ExceptionMessageIsOrContains extends \PHPUnit\Framework\Constraint\Constraint
  52934. {
  52935. private readonly string $expectedMessage;
  52936. public function __construct(string $expectedMessage)
  52937. {
  52938. $this->expectedMessage = $expectedMessage;
  52939. }
  52940. public function toString(): string
  52941. {
  52942. if ($this->expectedMessage === '') {
  52943. return 'exception message is empty';
  52944. }
  52945. return 'exception message contains ' . Exporter::export($this->expectedMessage);
  52946. }
  52947. protected function matches(mixed $other): bool
  52948. {
  52949. if ($this->expectedMessage === '') {
  52950. return $other === '';
  52951. }
  52952. return str_contains((string) $other, $this->expectedMessage);
  52953. }
  52954. /**
  52955. * Returns the description of the failure.
  52956. *
  52957. * The beginning of failure messages is "Failed asserting that" in most
  52958. * cases. This method should return the second part of that sentence.
  52959. */
  52960. protected function failureDescription(mixed $other): string
  52961. {
  52962. if ($this->expectedMessage === '') {
  52963. return sprintf("exception message is empty but is '%s'", $other);
  52964. }
  52965. return sprintf("exception message '%s' contains '%s'", $other, $this->expectedMessage);
  52966. }
  52967. }
  52968. <?php
  52969. declare (strict_types=1);
  52970. /*
  52971. * This file is part of PHPUnit.
  52972. *
  52973. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52974. *
  52975. * For the full copyright and license information, please view the LICENSE
  52976. * file that was distributed with this source code.
  52977. */
  52978. namespace PHPUnit\Framework\Constraint;
  52979. use function preg_match;
  52980. use function sprintf;
  52981. use Exception;
  52982. use PHPUnit\Util\Exporter;
  52983. /**
  52984. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  52985. *
  52986. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  52987. */
  52988. final class ExceptionMessageMatchesRegularExpression extends \PHPUnit\Framework\Constraint\Constraint
  52989. {
  52990. private readonly string $regularExpression;
  52991. public function __construct(string $regularExpression)
  52992. {
  52993. $this->regularExpression = $regularExpression;
  52994. }
  52995. public function toString(): string
  52996. {
  52997. return 'exception message matches ' . Exporter::export($this->regularExpression);
  52998. }
  52999. /**
  53000. * Evaluates the constraint for parameter $other. Returns true if the
  53001. * constraint is met, false otherwise.
  53002. *
  53003. * @throws \PHPUnit\Framework\Exception
  53004. * @throws Exception
  53005. */
  53006. protected function matches(mixed $other): bool
  53007. {
  53008. $match = @preg_match($this->regularExpression, (string) $other);
  53009. if ($match === \false) {
  53010. throw new \PHPUnit\Framework\Exception(sprintf('Invalid expected exception message regular expression given: %s', $this->regularExpression));
  53011. }
  53012. return $match === 1;
  53013. }
  53014. /**
  53015. * Returns the description of the failure.
  53016. *
  53017. * The beginning of failure messages is "Failed asserting that" in most
  53018. * cases. This method should return the second part of that sentence.
  53019. */
  53020. protected function failureDescription(mixed $other): string
  53021. {
  53022. return sprintf("exception message '%s' matches '%s'", $other, $this->regularExpression);
  53023. }
  53024. }
  53025. <?php
  53026. declare (strict_types=1);
  53027. /*
  53028. * This file is part of PHPUnit.
  53029. *
  53030. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53031. *
  53032. * For the full copyright and license information, please view the LICENSE
  53033. * file that was distributed with this source code.
  53034. */
  53035. namespace PHPUnit\Framework\Constraint;
  53036. use function is_dir;
  53037. use function sprintf;
  53038. /**
  53039. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53040. */
  53041. final class DirectoryExists extends \PHPUnit\Framework\Constraint\Constraint
  53042. {
  53043. /**
  53044. * Returns a string representation of the constraint.
  53045. */
  53046. public function toString(): string
  53047. {
  53048. return 'directory exists';
  53049. }
  53050. /**
  53051. * Evaluates the constraint for parameter $other. Returns true if the
  53052. * constraint is met, false otherwise.
  53053. */
  53054. protected function matches(mixed $other): bool
  53055. {
  53056. return is_dir($other);
  53057. }
  53058. /**
  53059. * Returns the description of the failure.
  53060. *
  53061. * The beginning of failure messages is "Failed asserting that" in most
  53062. * cases. This method should return the second part of that sentence.
  53063. */
  53064. protected function failureDescription(mixed $other): string
  53065. {
  53066. return sprintf('directory "%s" exists', $other);
  53067. }
  53068. }
  53069. <?php
  53070. declare (strict_types=1);
  53071. /*
  53072. * This file is part of PHPUnit.
  53073. *
  53074. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53075. *
  53076. * For the full copyright and license information, please view the LICENSE
  53077. * file that was distributed with this source code.
  53078. */
  53079. namespace PHPUnit\Framework\Constraint;
  53080. use function file_exists;
  53081. use function sprintf;
  53082. /**
  53083. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53084. */
  53085. final class FileExists extends \PHPUnit\Framework\Constraint\Constraint
  53086. {
  53087. /**
  53088. * Returns a string representation of the constraint.
  53089. */
  53090. public function toString(): string
  53091. {
  53092. return 'file exists';
  53093. }
  53094. /**
  53095. * Evaluates the constraint for parameter $other. Returns true if the
  53096. * constraint is met, false otherwise.
  53097. */
  53098. protected function matches(mixed $other): bool
  53099. {
  53100. return file_exists($other);
  53101. }
  53102. /**
  53103. * Returns the description of the failure.
  53104. *
  53105. * The beginning of failure messages is "Failed asserting that" in most
  53106. * cases. This method should return the second part of that sentence.
  53107. */
  53108. protected function failureDescription(mixed $other): string
  53109. {
  53110. return sprintf('file "%s" exists', $other);
  53111. }
  53112. }
  53113. <?php
  53114. declare (strict_types=1);
  53115. /*
  53116. * This file is part of PHPUnit.
  53117. *
  53118. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53119. *
  53120. * For the full copyright and license information, please view the LICENSE
  53121. * file that was distributed with this source code.
  53122. */
  53123. namespace PHPUnit\Framework\Constraint;
  53124. use function is_readable;
  53125. use function sprintf;
  53126. /**
  53127. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53128. */
  53129. final class IsReadable extends \PHPUnit\Framework\Constraint\Constraint
  53130. {
  53131. /**
  53132. * Returns a string representation of the constraint.
  53133. */
  53134. public function toString(): string
  53135. {
  53136. return 'is readable';
  53137. }
  53138. /**
  53139. * Evaluates the constraint for parameter $other. Returns true if the
  53140. * constraint is met, false otherwise.
  53141. */
  53142. protected function matches(mixed $other): bool
  53143. {
  53144. return is_readable($other);
  53145. }
  53146. /**
  53147. * Returns the description of the failure.
  53148. *
  53149. * The beginning of failure messages is "Failed asserting that" in most
  53150. * cases. This method should return the second part of that sentence.
  53151. */
  53152. protected function failureDescription(mixed $other): string
  53153. {
  53154. return sprintf('"%s" is readable', $other);
  53155. }
  53156. }
  53157. <?php
  53158. declare (strict_types=1);
  53159. /*
  53160. * This file is part of PHPUnit.
  53161. *
  53162. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53163. *
  53164. * For the full copyright and license information, please view the LICENSE
  53165. * file that was distributed with this source code.
  53166. */
  53167. namespace PHPUnit\Framework\Constraint;
  53168. use function is_writable;
  53169. use function sprintf;
  53170. /**
  53171. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53172. */
  53173. final class IsWritable extends \PHPUnit\Framework\Constraint\Constraint
  53174. {
  53175. /**
  53176. * Returns a string representation of the constraint.
  53177. */
  53178. public function toString(): string
  53179. {
  53180. return 'is writable';
  53181. }
  53182. /**
  53183. * Evaluates the constraint for parameter $other. Returns true if the
  53184. * constraint is met, false otherwise.
  53185. */
  53186. protected function matches(mixed $other): bool
  53187. {
  53188. return is_writable($other);
  53189. }
  53190. /**
  53191. * Returns the description of the failure.
  53192. *
  53193. * The beginning of failure messages is "Failed asserting that" in most
  53194. * cases. This method should return the second part of that sentence.
  53195. */
  53196. protected function failureDescription(mixed $other): string
  53197. {
  53198. return sprintf('"%s" is writable', $other);
  53199. }
  53200. }
  53201. <?php
  53202. declare (strict_types=1);
  53203. /*
  53204. * This file is part of PHPUnit.
  53205. *
  53206. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53207. *
  53208. * For the full copyright and license information, please view the LICENSE
  53209. * file that was distributed with this source code.
  53210. */
  53211. namespace PHPUnit\Framework\Constraint;
  53212. use PHPUnit\Framework\ExpectationFailedException;
  53213. /**
  53214. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53215. */
  53216. final class IsAnything extends \PHPUnit\Framework\Constraint\Constraint
  53217. {
  53218. /**
  53219. * Evaluates the constraint for parameter $other.
  53220. *
  53221. * If $returnResult is set to false (the default), an exception is thrown
  53222. * in case of a failure. null is returned otherwise.
  53223. *
  53224. * If $returnResult is true, the result of the evaluation is returned as
  53225. * a boolean value instead: true in case of success, false in case of a
  53226. * failure.
  53227. *
  53228. * @throws ExpectationFailedException
  53229. */
  53230. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  53231. {
  53232. return $returnResult ? \true : null;
  53233. }
  53234. /**
  53235. * Returns a string representation of the constraint.
  53236. */
  53237. public function toString(): string
  53238. {
  53239. return 'is anything';
  53240. }
  53241. /**
  53242. * Counts the number of constraint elements.
  53243. */
  53244. public function count(): int
  53245. {
  53246. return 0;
  53247. }
  53248. }
  53249. <?php
  53250. declare (strict_types=1);
  53251. /*
  53252. * This file is part of PHPUnit.
  53253. *
  53254. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53255. *
  53256. * For the full copyright and license information, please view the LICENSE
  53257. * file that was distributed with this source code.
  53258. */
  53259. namespace PHPUnit\Framework\Constraint;
  53260. use function explode;
  53261. use function gettype;
  53262. use function is_array;
  53263. use function is_object;
  53264. use function is_string;
  53265. use function sprintf;
  53266. use PHPUnit\Framework\ExpectationFailedException;
  53267. use PHPUnit\Util\Exporter;
  53268. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  53269. use UnitEnum;
  53270. /**
  53271. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53272. */
  53273. final class IsIdentical extends \PHPUnit\Framework\Constraint\Constraint
  53274. {
  53275. private readonly mixed $value;
  53276. public function __construct(mixed $value)
  53277. {
  53278. $this->value = $value;
  53279. }
  53280. /**
  53281. * Evaluates the constraint for parameter $other.
  53282. *
  53283. * If $returnResult is set to false (the default), an exception is thrown
  53284. * in case of a failure. null is returned otherwise.
  53285. *
  53286. * If $returnResult is true, the result of the evaluation is returned as
  53287. * a boolean value instead: true in case of success, false in case of a
  53288. * failure.
  53289. *
  53290. * @throws ExpectationFailedException
  53291. */
  53292. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
  53293. {
  53294. $success = $this->value === $other;
  53295. if ($returnResult) {
  53296. return $success;
  53297. }
  53298. if (!$success) {
  53299. $f = null;
  53300. // if both values are strings, make sure a diff is generated
  53301. if (is_string($this->value) && is_string($other)) {
  53302. $f = new ComparisonFailure($this->value, $other, sprintf("'%s'", $this->value), sprintf("'%s'", $other));
  53303. }
  53304. // if both values are array or enums, make sure a diff is generated
  53305. if (is_array($this->value) && is_array($other) || $this->value instanceof UnitEnum && $other instanceof UnitEnum) {
  53306. $f = new ComparisonFailure($this->value, $other, Exporter::export($this->value, \true), Exporter::export($other, \true));
  53307. }
  53308. $this->fail($other, $description, $f);
  53309. }
  53310. return null;
  53311. }
  53312. /**
  53313. * Returns a string representation of the constraint.
  53314. */
  53315. public function toString(bool $exportObjects = \false): string
  53316. {
  53317. if (is_object($this->value)) {
  53318. return 'is identical to an object of class "' . $this->value::class . '"';
  53319. }
  53320. return 'is identical to ' . Exporter::export($this->value, $exportObjects);
  53321. }
  53322. /**
  53323. * Returns the description of the failure.
  53324. *
  53325. * The beginning of failure messages is "Failed asserting that" in most
  53326. * cases. This method should return the second part of that sentence.
  53327. */
  53328. protected function failureDescription(mixed $other): string
  53329. {
  53330. if (is_object($this->value) && is_object($other)) {
  53331. return 'two variables reference the same object';
  53332. }
  53333. if (explode(' ', gettype($this->value), 2)[0] === 'resource' && explode(' ', gettype($other), 2)[0] === 'resource') {
  53334. return 'two variables reference the same resource';
  53335. }
  53336. if (is_string($this->value) && is_string($other)) {
  53337. return 'two strings are identical';
  53338. }
  53339. if (is_array($this->value) && is_array($other)) {
  53340. return 'two arrays are identical';
  53341. }
  53342. return parent::failureDescription($other);
  53343. }
  53344. }
  53345. <?php
  53346. declare (strict_types=1);
  53347. /*
  53348. * This file is part of PHPUnit.
  53349. *
  53350. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53351. *
  53352. * For the full copyright and license information, please view the LICENSE
  53353. * file that was distributed with this source code.
  53354. */
  53355. namespace PHPUnit\Framework\Constraint;
  53356. use function json_decode;
  53357. use function sprintf;
  53358. use PHPUnit\Framework\ExpectationFailedException;
  53359. use PHPUnit\Util\InvalidJsonException;
  53360. use PHPUnit\Util\Json;
  53361. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  53362. /**
  53363. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53364. */
  53365. final class JsonMatches extends \PHPUnit\Framework\Constraint\Constraint
  53366. {
  53367. private readonly string $value;
  53368. public function __construct(string $value)
  53369. {
  53370. $this->value = $value;
  53371. }
  53372. /**
  53373. * Returns a string representation of the object.
  53374. */
  53375. public function toString(): string
  53376. {
  53377. return sprintf('matches JSON string "%s"', $this->value);
  53378. }
  53379. /**
  53380. * Evaluates the constraint for parameter $other. Returns true if the
  53381. * constraint is met, false otherwise.
  53382. *
  53383. * This method can be overridden to implement the evaluation algorithm.
  53384. */
  53385. protected function matches(mixed $other): bool
  53386. {
  53387. [$error, $recodedOther] = Json::canonicalize($other);
  53388. if ($error) {
  53389. return \false;
  53390. }
  53391. [$error, $recodedValue] = Json::canonicalize($this->value);
  53392. if ($error) {
  53393. return \false;
  53394. }
  53395. return $recodedOther == $recodedValue;
  53396. }
  53397. /**
  53398. * Throws an exception for the given compared value and test description.
  53399. *
  53400. * @throws ExpectationFailedException
  53401. * @throws InvalidJsonException
  53402. */
  53403. protected function fail(mixed $other, string $description, ?ComparisonFailure $comparisonFailure = null): never
  53404. {
  53405. if ($comparisonFailure === null) {
  53406. [$error, $recodedOther] = Json::canonicalize($other);
  53407. if ($error) {
  53408. parent::fail($other, $description);
  53409. }
  53410. [$error, $recodedValue] = Json::canonicalize($this->value);
  53411. if ($error) {
  53412. parent::fail($other, $description);
  53413. }
  53414. $comparisonFailure = new ComparisonFailure(json_decode($this->value), json_decode($other), Json::prettify($recodedValue), Json::prettify($recodedOther), 'Failed asserting that two json values are equal.');
  53415. }
  53416. parent::fail($other, $description, $comparisonFailure);
  53417. }
  53418. }
  53419. <?php
  53420. declare (strict_types=1);
  53421. /*
  53422. * This file is part of PHPUnit.
  53423. *
  53424. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53425. *
  53426. * For the full copyright and license information, please view the LICENSE
  53427. * file that was distributed with this source code.
  53428. */
  53429. namespace PHPUnit\Framework\Constraint;
  53430. use function is_finite;
  53431. /**
  53432. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53433. */
  53434. final class IsFinite extends \PHPUnit\Framework\Constraint\Constraint
  53435. {
  53436. /**
  53437. * Returns a string representation of the constraint.
  53438. */
  53439. public function toString(): string
  53440. {
  53441. return 'is finite';
  53442. }
  53443. /**
  53444. * Evaluates the constraint for parameter $other. Returns true if the
  53445. * constraint is met, false otherwise.
  53446. */
  53447. protected function matches(mixed $other): bool
  53448. {
  53449. return is_finite($other);
  53450. }
  53451. }
  53452. <?php
  53453. declare (strict_types=1);
  53454. /*
  53455. * This file is part of PHPUnit.
  53456. *
  53457. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53458. *
  53459. * For the full copyright and license information, please view the LICENSE
  53460. * file that was distributed with this source code.
  53461. */
  53462. namespace PHPUnit\Framework\Constraint;
  53463. use function is_infinite;
  53464. /**
  53465. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53466. */
  53467. final class IsInfinite extends \PHPUnit\Framework\Constraint\Constraint
  53468. {
  53469. /**
  53470. * Returns a string representation of the constraint.
  53471. */
  53472. public function toString(): string
  53473. {
  53474. return 'is infinite';
  53475. }
  53476. /**
  53477. * Evaluates the constraint for parameter $other. Returns true if the
  53478. * constraint is met, false otherwise.
  53479. */
  53480. protected function matches(mixed $other): bool
  53481. {
  53482. return is_infinite($other);
  53483. }
  53484. }
  53485. <?php
  53486. declare (strict_types=1);
  53487. /*
  53488. * This file is part of PHPUnit.
  53489. *
  53490. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53491. *
  53492. * For the full copyright and license information, please view the LICENSE
  53493. * file that was distributed with this source code.
  53494. */
  53495. namespace PHPUnit\Framework\Constraint;
  53496. use function is_nan;
  53497. /**
  53498. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53499. */
  53500. final class IsNan extends \PHPUnit\Framework\Constraint\Constraint
  53501. {
  53502. /**
  53503. * Returns a string representation of the constraint.
  53504. */
  53505. public function toString(): string
  53506. {
  53507. return 'is nan';
  53508. }
  53509. /**
  53510. * Evaluates the constraint for parameter $other. Returns true if the
  53511. * constraint is met, false otherwise.
  53512. */
  53513. protected function matches(mixed $other): bool
  53514. {
  53515. return is_nan($other);
  53516. }
  53517. }
  53518. <?php
  53519. declare (strict_types=1);
  53520. /*
  53521. * This file is part of PHPUnit.
  53522. *
  53523. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53524. *
  53525. * For the full copyright and license information, please view the LICENSE
  53526. * file that was distributed with this source code.
  53527. */
  53528. namespace PHPUnit\Framework\Constraint;
  53529. use function is_object;
  53530. use PHPUnit\Framework\ActualValueIsNotAnObjectException;
  53531. use PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException;
  53532. use PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException;
  53533. use PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException;
  53534. use PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException;
  53535. use PHPUnit\Framework\ComparisonMethodDoesNotExistException;
  53536. use ReflectionNamedType;
  53537. use ReflectionObject;
  53538. /**
  53539. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53540. */
  53541. final class ObjectEquals extends \PHPUnit\Framework\Constraint\Constraint
  53542. {
  53543. private readonly object $expected;
  53544. private readonly string $method;
  53545. public function __construct(object $object, string $method = 'equals')
  53546. {
  53547. $this->expected = $object;
  53548. $this->method = $method;
  53549. }
  53550. public function toString(): string
  53551. {
  53552. return 'two objects are equal';
  53553. }
  53554. /**
  53555. * @throws ActualValueIsNotAnObjectException
  53556. * @throws ComparisonMethodDoesNotAcceptParameterTypeException
  53557. * @throws ComparisonMethodDoesNotDeclareBoolReturnTypeException
  53558. * @throws ComparisonMethodDoesNotDeclareExactlyOneParameterException
  53559. * @throws ComparisonMethodDoesNotDeclareParameterTypeException
  53560. * @throws ComparisonMethodDoesNotExistException
  53561. */
  53562. protected function matches(mixed $other): bool
  53563. {
  53564. if (!is_object($other)) {
  53565. throw new ActualValueIsNotAnObjectException();
  53566. }
  53567. $object = new ReflectionObject($other);
  53568. if (!$object->hasMethod($this->method)) {
  53569. throw new ComparisonMethodDoesNotExistException($other::class, $this->method);
  53570. }
  53571. $method = $object->getMethod($this->method);
  53572. if (!$method->hasReturnType()) {
  53573. throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
  53574. }
  53575. $returnType = $method->getReturnType();
  53576. if (!$returnType instanceof ReflectionNamedType) {
  53577. throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
  53578. }
  53579. if ($returnType->allowsNull()) {
  53580. throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
  53581. }
  53582. if ($returnType->getName() !== 'bool') {
  53583. throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
  53584. }
  53585. if ($method->getNumberOfParameters() !== 1 || $method->getNumberOfRequiredParameters() !== 1) {
  53586. throw new ComparisonMethodDoesNotDeclareExactlyOneParameterException($other::class, $this->method);
  53587. }
  53588. $parameter = $method->getParameters()[0];
  53589. if (!$parameter->hasType()) {
  53590. throw new ComparisonMethodDoesNotDeclareParameterTypeException($other::class, $this->method);
  53591. }
  53592. $type = $parameter->getType();
  53593. if (!$type instanceof ReflectionNamedType) {
  53594. throw new ComparisonMethodDoesNotDeclareParameterTypeException($other::class, $this->method);
  53595. }
  53596. $typeName = $type->getName();
  53597. if ($typeName === 'self') {
  53598. $typeName = $other::class;
  53599. }
  53600. if (!$this->expected instanceof $typeName) {
  53601. throw new ComparisonMethodDoesNotAcceptParameterTypeException($other::class, $this->method, $this->expected::class);
  53602. }
  53603. return $other->{$this->method}($this->expected);
  53604. }
  53605. protected function failureDescription(mixed $other): string
  53606. {
  53607. return $this->toString(\true);
  53608. }
  53609. }
  53610. <?php
  53611. declare (strict_types=1);
  53612. /*
  53613. * This file is part of PHPUnit.
  53614. *
  53615. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53616. *
  53617. * For the full copyright and license information, please view the LICENSE
  53618. * file that was distributed with this source code.
  53619. */
  53620. namespace PHPUnit\Framework\Constraint;
  53621. use function gettype;
  53622. use function is_object;
  53623. use function sprintf;
  53624. use ReflectionObject;
  53625. /**
  53626. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53627. */
  53628. final class ObjectHasProperty extends \PHPUnit\Framework\Constraint\Constraint
  53629. {
  53630. private readonly string $propertyName;
  53631. public function __construct(string $propertyName)
  53632. {
  53633. $this->propertyName = $propertyName;
  53634. }
  53635. /**
  53636. * Returns a string representation of the constraint.
  53637. */
  53638. public function toString(): string
  53639. {
  53640. return sprintf('has property "%s"', $this->propertyName);
  53641. }
  53642. /**
  53643. * Evaluates the constraint for parameter $other. Returns true if the
  53644. * constraint is met, false otherwise.
  53645. *
  53646. * @param mixed $other value or object to evaluate
  53647. */
  53648. protected function matches(mixed $other): bool
  53649. {
  53650. if (!is_object($other)) {
  53651. return \false;
  53652. }
  53653. return (new ReflectionObject($other))->hasProperty($this->propertyName);
  53654. }
  53655. /**
  53656. * Returns the description of the failure.
  53657. *
  53658. * The beginning of failure messages is "Failed asserting that" in most
  53659. * cases. This method should return the second part of that sentence.
  53660. *
  53661. * @param mixed $other evaluated value or object
  53662. */
  53663. protected function failureDescription(mixed $other): string
  53664. {
  53665. if (is_object($other)) {
  53666. return sprintf('object of class "%s" %s', $other::class, $this->toString(\true));
  53667. }
  53668. return sprintf('"%s" (%s) %s', $other, gettype($other), $this->toString(\true));
  53669. }
  53670. }
  53671. <?php
  53672. declare (strict_types=1);
  53673. /*
  53674. * This file is part of PHPUnit.
  53675. *
  53676. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53677. *
  53678. * For the full copyright and license information, please view the LICENSE
  53679. * file that was distributed with this source code.
  53680. */
  53681. namespace PHPUnit\Framework\Constraint;
  53682. use function array_map;
  53683. use function count;
  53684. /**
  53685. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53686. */
  53687. abstract class BinaryOperator extends \PHPUnit\Framework\Constraint\Operator
  53688. {
  53689. /**
  53690. * @psalm-var list<Constraint>
  53691. */
  53692. private readonly array $constraints;
  53693. protected function __construct(mixed ...$constraints)
  53694. {
  53695. $this->constraints = array_map(fn($constraint): \PHPUnit\Framework\Constraint\Constraint => $this->checkConstraint($constraint), $constraints);
  53696. }
  53697. /**
  53698. * Returns the number of operands (constraints).
  53699. */
  53700. final public function arity(): int
  53701. {
  53702. return count($this->constraints);
  53703. }
  53704. /**
  53705. * Returns a string representation of the constraint.
  53706. */
  53707. public function toString(): string
  53708. {
  53709. $reduced = $this->reduce();
  53710. if ($reduced !== $this) {
  53711. return $reduced->toString();
  53712. }
  53713. $text = '';
  53714. foreach ($this->constraints as $key => $constraint) {
  53715. $constraint = $constraint->reduce();
  53716. $text .= $this->constraintToString($constraint, $key);
  53717. }
  53718. return $text;
  53719. }
  53720. /**
  53721. * Counts the number of constraint elements.
  53722. */
  53723. public function count(): int
  53724. {
  53725. $count = 0;
  53726. foreach ($this->constraints as $constraint) {
  53727. $count += count($constraint);
  53728. }
  53729. return $count;
  53730. }
  53731. /**
  53732. * @psalm-return list<Constraint>
  53733. */
  53734. final protected function constraints(): array
  53735. {
  53736. return $this->constraints;
  53737. }
  53738. /**
  53739. * Returns true if the $constraint needs to be wrapped with braces.
  53740. */
  53741. final protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
  53742. {
  53743. return $this->arity() > 1 && parent::constraintNeedsParentheses($constraint);
  53744. }
  53745. /**
  53746. * Reduces the sub-expression starting at $this by skipping degenerate
  53747. * sub-expression and returns first descendant constraint that starts
  53748. * a non-reducible sub-expression.
  53749. *
  53750. * See Constraint::reduce() for more.
  53751. */
  53752. protected function reduce(): \PHPUnit\Framework\Constraint\Constraint
  53753. {
  53754. if ($this->arity() === 1 && $this->constraints[0] instanceof \PHPUnit\Framework\Constraint\Operator) {
  53755. return $this->constraints[0]->reduce();
  53756. }
  53757. return parent::reduce();
  53758. }
  53759. /**
  53760. * Returns string representation of given operand in context of this operator.
  53761. */
  53762. private function constraintToString(\PHPUnit\Framework\Constraint\Constraint $constraint, int $position): string
  53763. {
  53764. $prefix = '';
  53765. if ($position > 0) {
  53766. $prefix = ' ' . $this->operator() . ' ';
  53767. }
  53768. if ($this->constraintNeedsParentheses($constraint)) {
  53769. return $prefix . '( ' . $constraint->toString() . ' )';
  53770. }
  53771. $string = $constraint->toStringInContext($this, $position);
  53772. if ($string === '') {
  53773. $string = $constraint->toString();
  53774. }
  53775. return $prefix . $string;
  53776. }
  53777. }
  53778. <?php
  53779. declare (strict_types=1);
  53780. /*
  53781. * This file is part of PHPUnit.
  53782. *
  53783. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53784. *
  53785. * For the full copyright and license information, please view the LICENSE
  53786. * file that was distributed with this source code.
  53787. */
  53788. namespace PHPUnit\Framework\Constraint;
  53789. /**
  53790. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53791. */
  53792. final class LogicalAnd extends \PHPUnit\Framework\Constraint\BinaryOperator
  53793. {
  53794. public static function fromConstraints(mixed ...$constraints): self
  53795. {
  53796. return new self(...$constraints);
  53797. }
  53798. /**
  53799. * Returns the name of this operator.
  53800. */
  53801. public function operator(): string
  53802. {
  53803. return 'and';
  53804. }
  53805. /**
  53806. * Returns this operator's precedence.
  53807. *
  53808. * @see https://www.php.net/manual/en/language.operators.precedence.php
  53809. */
  53810. public function precedence(): int
  53811. {
  53812. return 22;
  53813. }
  53814. /**
  53815. * Evaluates the constraint for parameter $other. Returns true if the
  53816. * constraint is met, false otherwise.
  53817. */
  53818. protected function matches(mixed $other): bool
  53819. {
  53820. foreach ($this->constraints() as $constraint) {
  53821. if (!$constraint->evaluate($other, '', \true)) {
  53822. return \false;
  53823. }
  53824. }
  53825. return [] !== $this->constraints();
  53826. }
  53827. }
  53828. <?php
  53829. declare (strict_types=1);
  53830. /*
  53831. * This file is part of PHPUnit.
  53832. *
  53833. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53834. *
  53835. * For the full copyright and license information, please view the LICENSE
  53836. * file that was distributed with this source code.
  53837. */
  53838. namespace PHPUnit\Framework\Constraint;
  53839. use function array_map;
  53840. use function count;
  53841. use function preg_match;
  53842. use function preg_quote;
  53843. use function preg_replace;
  53844. use PHPUnit\Framework\ExpectationFailedException;
  53845. /**
  53846. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53847. */
  53848. final class LogicalNot extends \PHPUnit\Framework\Constraint\UnaryOperator
  53849. {
  53850. public static function negate(string $string): string
  53851. {
  53852. $positives = ['contains ', 'exists', 'has ', 'is ', 'are ', 'matches ', 'starts with ', 'ends with ', 'reference ', 'not not '];
  53853. $negatives = ['does not contain ', 'does not exist', 'does not have ', 'is not ', 'are not ', 'does not match ', 'starts not with ', 'ends not with ', 'don\'t reference ', 'not '];
  53854. preg_match('/(\'[\w\W]*\')([\w\W]*)("[\w\W]*")/i', $string, $matches);
  53855. if (count($matches) === 0) {
  53856. preg_match('/(\'[\w\W]*\')([\w\W]*)(\'[\w\W]*\')/i', $string, $matches);
  53857. }
  53858. $positives = array_map(static fn(string $s) => '/\b' . preg_quote($s, '/') . '/', $positives);
  53859. if (count($matches) > 0) {
  53860. $nonInput = $matches[2];
  53861. $negatedString = preg_replace('/' . preg_quote($nonInput, '/') . '/', preg_replace($positives, $negatives, $nonInput), $string);
  53862. } else {
  53863. $negatedString = preg_replace($positives, $negatives, $string);
  53864. }
  53865. return $negatedString;
  53866. }
  53867. /**
  53868. * Returns the name of this operator.
  53869. */
  53870. public function operator(): string
  53871. {
  53872. return 'not';
  53873. }
  53874. /**
  53875. * Returns this operator's precedence.
  53876. *
  53877. * @see https://www.php.net/manual/en/language.operators.precedence.php
  53878. */
  53879. public function precedence(): int
  53880. {
  53881. return 5;
  53882. }
  53883. /**
  53884. * Evaluates the constraint for parameter $other. Returns true if the
  53885. * constraint is met, false otherwise.
  53886. *
  53887. * @throws ExpectationFailedException
  53888. */
  53889. protected function matches(mixed $other): bool
  53890. {
  53891. return !$this->constraint()->evaluate($other, '', \true);
  53892. }
  53893. /**
  53894. * Applies additional transformation to strings returned by toString() or
  53895. * failureDescription().
  53896. */
  53897. protected function transformString(string $string): string
  53898. {
  53899. return self::negate($string);
  53900. }
  53901. /**
  53902. * Reduces the sub-expression starting at $this by skipping degenerate
  53903. * sub-expression and returns first descendant constraint that starts
  53904. * a non-reducible sub-expression.
  53905. *
  53906. * See Constraint::reduce() for more.
  53907. */
  53908. protected function reduce(): \PHPUnit\Framework\Constraint\Constraint
  53909. {
  53910. $constraint = $this->constraint();
  53911. if ($constraint instanceof self) {
  53912. return $constraint->constraint()->reduce();
  53913. }
  53914. return parent::reduce();
  53915. }
  53916. }
  53917. <?php
  53918. declare (strict_types=1);
  53919. /*
  53920. * This file is part of PHPUnit.
  53921. *
  53922. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53923. *
  53924. * For the full copyright and license information, please view the LICENSE
  53925. * file that was distributed with this source code.
  53926. */
  53927. namespace PHPUnit\Framework\Constraint;
  53928. /**
  53929. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53930. */
  53931. final class LogicalOr extends \PHPUnit\Framework\Constraint\BinaryOperator
  53932. {
  53933. public static function fromConstraints(mixed ...$constraints): self
  53934. {
  53935. return new self(...$constraints);
  53936. }
  53937. /**
  53938. * Returns the name of this operator.
  53939. */
  53940. public function operator(): string
  53941. {
  53942. return 'or';
  53943. }
  53944. /**
  53945. * Returns this operator's precedence.
  53946. *
  53947. * @see https://www.php.net/manual/en/language.operators.precedence.php
  53948. */
  53949. public function precedence(): int
  53950. {
  53951. return 24;
  53952. }
  53953. /**
  53954. * Evaluates the constraint for parameter $other. Returns true if the
  53955. * constraint is met, false otherwise.
  53956. */
  53957. public function matches(mixed $other): bool
  53958. {
  53959. foreach ($this->constraints() as $constraint) {
  53960. if ($constraint->evaluate($other, '', \true)) {
  53961. return \true;
  53962. }
  53963. }
  53964. return \false;
  53965. }
  53966. }
  53967. <?php
  53968. declare (strict_types=1);
  53969. /*
  53970. * This file is part of PHPUnit.
  53971. *
  53972. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53973. *
  53974. * For the full copyright and license information, please view the LICENSE
  53975. * file that was distributed with this source code.
  53976. */
  53977. namespace PHPUnit\Framework\Constraint;
  53978. use function array_reduce;
  53979. use function array_shift;
  53980. use PHPUnit\Framework\ExpectationFailedException;
  53981. /**
  53982. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  53983. */
  53984. final class LogicalXor extends \PHPUnit\Framework\Constraint\BinaryOperator
  53985. {
  53986. public static function fromConstraints(mixed ...$constraints): self
  53987. {
  53988. return new self(...$constraints);
  53989. }
  53990. /**
  53991. * Returns the name of this operator.
  53992. */
  53993. public function operator(): string
  53994. {
  53995. return 'xor';
  53996. }
  53997. /**
  53998. * Returns this operator's precedence.
  53999. *
  54000. * @see https://www.php.net/manual/en/language.operators.precedence.php.
  54001. */
  54002. public function precedence(): int
  54003. {
  54004. return 23;
  54005. }
  54006. /**
  54007. * Evaluates the constraint for parameter $other. Returns true if the
  54008. * constraint is met, false otherwise.
  54009. *
  54010. * @throws ExpectationFailedException
  54011. */
  54012. public function matches(mixed $other): bool
  54013. {
  54014. $constraints = $this->constraints();
  54015. $initial = array_shift($constraints);
  54016. if ($initial === null) {
  54017. return \false;
  54018. }
  54019. return array_reduce($constraints, static fn(bool $matches, \PHPUnit\Framework\Constraint\Constraint $constraint): bool => $matches xor $constraint->evaluate($other, '', \true), $initial->evaluate($other, '', \true));
  54020. }
  54021. }
  54022. <?php
  54023. declare (strict_types=1);
  54024. /*
  54025. * This file is part of PHPUnit.
  54026. *
  54027. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54028. *
  54029. * For the full copyright and license information, please view the LICENSE
  54030. * file that was distributed with this source code.
  54031. */
  54032. namespace PHPUnit\Framework\Constraint;
  54033. /**
  54034. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54035. */
  54036. abstract class Operator extends \PHPUnit\Framework\Constraint\Constraint
  54037. {
  54038. /**
  54039. * Returns the name of this operator.
  54040. */
  54041. abstract public function operator(): string;
  54042. /**
  54043. * Returns this operator's precedence.
  54044. *
  54045. * @see https://www.php.net/manual/en/language.operators.precedence.php
  54046. */
  54047. abstract public function precedence(): int;
  54048. /**
  54049. * Returns the number of operands.
  54050. */
  54051. abstract public function arity(): int;
  54052. /**
  54053. * Validates $constraint argument.
  54054. */
  54055. protected function checkConstraint(mixed $constraint): \PHPUnit\Framework\Constraint\Constraint
  54056. {
  54057. if (!$constraint instanceof \PHPUnit\Framework\Constraint\Constraint) {
  54058. return new \PHPUnit\Framework\Constraint\IsEqual($constraint);
  54059. }
  54060. return $constraint;
  54061. }
  54062. /**
  54063. * Returns true if the $constraint needs to be wrapped with braces.
  54064. */
  54065. protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
  54066. {
  54067. return $constraint instanceof self && $constraint->arity() > 1 && $this->precedence() <= $constraint->precedence();
  54068. }
  54069. }
  54070. <?php
  54071. declare (strict_types=1);
  54072. /*
  54073. * This file is part of PHPUnit.
  54074. *
  54075. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54076. *
  54077. * For the full copyright and license information, please view the LICENSE
  54078. * file that was distributed with this source code.
  54079. */
  54080. namespace PHPUnit\Framework\Constraint;
  54081. use function count;
  54082. /**
  54083. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54084. */
  54085. abstract class UnaryOperator extends \PHPUnit\Framework\Constraint\Operator
  54086. {
  54087. private readonly \PHPUnit\Framework\Constraint\Constraint $constraint;
  54088. public function __construct(mixed $constraint)
  54089. {
  54090. $this->constraint = $this->checkConstraint($constraint);
  54091. }
  54092. /**
  54093. * Returns the number of operands (constraints).
  54094. */
  54095. public function arity(): int
  54096. {
  54097. return 1;
  54098. }
  54099. /**
  54100. * Returns a string representation of the constraint.
  54101. */
  54102. public function toString(): string
  54103. {
  54104. $reduced = $this->reduce();
  54105. if ($reduced !== $this) {
  54106. return $reduced->toString();
  54107. }
  54108. $constraint = $this->constraint->reduce();
  54109. if ($this->constraintNeedsParentheses($constraint)) {
  54110. return $this->operator() . '( ' . $constraint->toString() . ' )';
  54111. }
  54112. $string = $constraint->toStringInContext($this, 0);
  54113. if ($string === '') {
  54114. return $this->transformString($constraint->toString());
  54115. }
  54116. return $string;
  54117. }
  54118. /**
  54119. * Counts the number of constraint elements.
  54120. */
  54121. public function count(): int
  54122. {
  54123. return count($this->constraint);
  54124. }
  54125. /**
  54126. * Returns the description of the failure.
  54127. *
  54128. * The beginning of failure messages is "Failed asserting that" in most
  54129. * cases. This method should return the second part of that sentence.
  54130. */
  54131. protected function failureDescription(mixed $other): string
  54132. {
  54133. $reduced = $this->reduce();
  54134. if ($reduced !== $this) {
  54135. return $reduced->failureDescription($other);
  54136. }
  54137. $constraint = $this->constraint->reduce();
  54138. if ($this->constraintNeedsParentheses($constraint)) {
  54139. return $this->operator() . '( ' . $constraint->failureDescription($other) . ' )';
  54140. }
  54141. $string = $constraint->failureDescriptionInContext($this, 0, $other);
  54142. if ($string === '') {
  54143. return $this->transformString($constraint->failureDescription($other));
  54144. }
  54145. return $string;
  54146. }
  54147. /**
  54148. * Transforms string returned by the member constraint's toString() or
  54149. * failureDescription() such that it reflects constraint's participation in
  54150. * this expression.
  54151. *
  54152. * The method may be overwritten in a subclass to apply default
  54153. * transformation in case the operand constraint does not provide its own
  54154. * custom strings via toStringInContext() or failureDescriptionInContext().
  54155. */
  54156. protected function transformString(string $string): string
  54157. {
  54158. return $string;
  54159. }
  54160. /**
  54161. * Provides access to $this->constraint for subclasses.
  54162. */
  54163. final protected function constraint(): \PHPUnit\Framework\Constraint\Constraint
  54164. {
  54165. return $this->constraint;
  54166. }
  54167. /**
  54168. * Returns true if the $constraint needs to be wrapped with parentheses.
  54169. */
  54170. protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
  54171. {
  54172. $constraint = $constraint->reduce();
  54173. return $constraint instanceof self || parent::constraintNeedsParentheses($constraint);
  54174. }
  54175. }
  54176. <?php
  54177. declare (strict_types=1);
  54178. /*
  54179. * This file is part of PHPUnit.
  54180. *
  54181. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54182. *
  54183. * For the full copyright and license information, please view the LICENSE
  54184. * file that was distributed with this source code.
  54185. */
  54186. namespace PHPUnit\Framework\Constraint;
  54187. use const JSON_ERROR_CTRL_CHAR;
  54188. use const JSON_ERROR_DEPTH;
  54189. use const JSON_ERROR_NONE;
  54190. use const JSON_ERROR_STATE_MISMATCH;
  54191. use const JSON_ERROR_SYNTAX;
  54192. use const JSON_ERROR_UTF8;
  54193. use function is_string;
  54194. use function json_decode;
  54195. use function json_last_error;
  54196. use function sprintf;
  54197. /**
  54198. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54199. */
  54200. final class IsJson extends \PHPUnit\Framework\Constraint\Constraint
  54201. {
  54202. /**
  54203. * Returns a string representation of the constraint.
  54204. */
  54205. public function toString(): string
  54206. {
  54207. return 'is valid JSON';
  54208. }
  54209. /**
  54210. * Evaluates the constraint for parameter $other. Returns true if the
  54211. * constraint is met, false otherwise.
  54212. */
  54213. protected function matches(mixed $other): bool
  54214. {
  54215. if (!is_string($other) || $other === '') {
  54216. return \false;
  54217. }
  54218. json_decode($other);
  54219. if (json_last_error()) {
  54220. return \false;
  54221. }
  54222. return \true;
  54223. }
  54224. /**
  54225. * Returns the description of the failure.
  54226. *
  54227. * The beginning of failure messages is "Failed asserting that" in most
  54228. * cases. This method should return the second part of that sentence.
  54229. */
  54230. protected function failureDescription(mixed $other): string
  54231. {
  54232. if (!is_string($other)) {
  54233. return $this->valueToTypeStringFragment($other) . 'is valid JSON';
  54234. }
  54235. if ($other === '') {
  54236. return 'an empty string is valid JSON';
  54237. }
  54238. return sprintf('a string is valid JSON (%s)', $this->determineJsonError($other));
  54239. }
  54240. private function determineJsonError(string $json): string
  54241. {
  54242. json_decode($json);
  54243. return match (json_last_error()) {
  54244. JSON_ERROR_NONE => '',
  54245. JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
  54246. JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
  54247. JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
  54248. JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
  54249. JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
  54250. default => 'Unknown error',
  54251. };
  54252. }
  54253. }
  54254. <?php
  54255. declare (strict_types=1);
  54256. /*
  54257. * This file is part of PHPUnit.
  54258. *
  54259. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54260. *
  54261. * For the full copyright and license information, please view the LICENSE
  54262. * file that was distributed with this source code.
  54263. */
  54264. namespace PHPUnit\Framework\Constraint;
  54265. use function preg_match;
  54266. use function sprintf;
  54267. /**
  54268. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54269. */
  54270. final class RegularExpression extends \PHPUnit\Framework\Constraint\Constraint
  54271. {
  54272. private readonly string $pattern;
  54273. public function __construct(string $pattern)
  54274. {
  54275. $this->pattern = $pattern;
  54276. }
  54277. /**
  54278. * Returns a string representation of the constraint.
  54279. */
  54280. public function toString(): string
  54281. {
  54282. return sprintf('matches PCRE pattern "%s"', $this->pattern);
  54283. }
  54284. /**
  54285. * Evaluates the constraint for parameter $other. Returns true if the
  54286. * constraint is met, false otherwise.
  54287. */
  54288. protected function matches(mixed $other): bool
  54289. {
  54290. return preg_match($this->pattern, $other) > 0;
  54291. }
  54292. }
  54293. <?php
  54294. declare (strict_types=1);
  54295. /*
  54296. * This file is part of PHPUnit.
  54297. *
  54298. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54299. *
  54300. * For the full copyright and license information, please view the LICENSE
  54301. * file that was distributed with this source code.
  54302. */
  54303. namespace PHPUnit\Framework\Constraint;
  54304. use function is_string;
  54305. use function mb_detect_encoding;
  54306. use function mb_stripos;
  54307. use function mb_strtolower;
  54308. use function sprintf;
  54309. use function str_contains;
  54310. use function strlen;
  54311. use function strtr;
  54312. use PHPUnit\Util\Exporter;
  54313. /**
  54314. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54315. */
  54316. final class StringContains extends \PHPUnit\Framework\Constraint\Constraint
  54317. {
  54318. private readonly string $needle;
  54319. private readonly bool $ignoreCase;
  54320. private readonly bool $ignoreLineEndings;
  54321. public function __construct(string $needle, bool $ignoreCase = \false, bool $ignoreLineEndings = \false)
  54322. {
  54323. if ($ignoreLineEndings) {
  54324. $needle = $this->normalizeLineEndings($needle);
  54325. }
  54326. $this->needle = $needle;
  54327. $this->ignoreCase = $ignoreCase;
  54328. $this->ignoreLineEndings = $ignoreLineEndings;
  54329. }
  54330. /**
  54331. * Returns a string representation of the constraint.
  54332. */
  54333. public function toString(): string
  54334. {
  54335. $needle = $this->needle;
  54336. if ($this->ignoreCase) {
  54337. $needle = mb_strtolower($this->needle, 'UTF-8');
  54338. }
  54339. return sprintf('contains "%s" [%s](length: %s)', $needle, $this->getDetectedEncoding($needle), strlen($needle));
  54340. }
  54341. public function failureDescription(mixed $other): string
  54342. {
  54343. $stringifiedHaystack = Exporter::export($other, \true);
  54344. $haystackEncoding = $this->getDetectedEncoding($other);
  54345. $haystackLength = $this->getHaystackLength($other);
  54346. $haystackInformation = sprintf('%s [%s](length: %s) ', $stringifiedHaystack, $haystackEncoding, $haystackLength);
  54347. $needleInformation = $this->toString(\true);
  54348. return $haystackInformation . $needleInformation;
  54349. }
  54350. /**
  54351. * Evaluates the constraint for parameter $other. Returns true if the
  54352. * constraint is met, false otherwise.
  54353. */
  54354. protected function matches(mixed $other): bool
  54355. {
  54356. $haystack = $other;
  54357. if ('' === $this->needle) {
  54358. return \true;
  54359. }
  54360. if (!is_string($haystack)) {
  54361. return \false;
  54362. }
  54363. if ($this->ignoreLineEndings) {
  54364. $haystack = $this->normalizeLineEndings($haystack);
  54365. }
  54366. if ($this->ignoreCase) {
  54367. /*
  54368. * We must use the multibyte-safe version, so we can accurately compare non-latin uppercase characters with
  54369. * their lowercase equivalents.
  54370. */
  54371. return mb_stripos($haystack, $this->needle, 0, 'UTF-8') !== \false;
  54372. }
  54373. /*
  54374. * Use the non-multibyte safe functions to see if the string is contained in $other.
  54375. *
  54376. * This function is very fast, and we don't care about the character position in the string.
  54377. *
  54378. * Additionally, we want this method to be binary safe, so we can check if some binary data is in other binary
  54379. * data.
  54380. */
  54381. return str_contains($haystack, $this->needle);
  54382. }
  54383. private function getDetectedEncoding(mixed $other): string
  54384. {
  54385. if ($this->ignoreCase) {
  54386. return 'Encoding ignored';
  54387. }
  54388. if (!is_string($other)) {
  54389. return 'Encoding detection failed';
  54390. }
  54391. $detectedEncoding = mb_detect_encoding($other, null, \true);
  54392. if ($detectedEncoding === \false) {
  54393. return 'Encoding detection failed';
  54394. }
  54395. return $detectedEncoding;
  54396. }
  54397. private function getHaystackLength(mixed $haystack): int
  54398. {
  54399. if (!is_string($haystack)) {
  54400. return 0;
  54401. }
  54402. if ($this->ignoreLineEndings) {
  54403. $haystack = $this->normalizeLineEndings($haystack);
  54404. }
  54405. return strlen($haystack);
  54406. }
  54407. private function normalizeLineEndings(string $string): string
  54408. {
  54409. return strtr($string, ["\r\n" => "\n", "\r" => "\n"]);
  54410. }
  54411. }
  54412. <?php
  54413. declare (strict_types=1);
  54414. /*
  54415. * This file is part of PHPUnit.
  54416. *
  54417. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54418. *
  54419. * For the full copyright and license information, please view the LICENSE
  54420. * file that was distributed with this source code.
  54421. */
  54422. namespace PHPUnit\Framework\Constraint;
  54423. use function str_ends_with;
  54424. use PHPUnit\Framework\EmptyStringException;
  54425. /**
  54426. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54427. */
  54428. final class StringEndsWith extends \PHPUnit\Framework\Constraint\Constraint
  54429. {
  54430. private readonly string $suffix;
  54431. /**
  54432. * @throws EmptyStringException
  54433. */
  54434. public function __construct(string $suffix)
  54435. {
  54436. if ($suffix === '') {
  54437. throw new EmptyStringException();
  54438. }
  54439. $this->suffix = $suffix;
  54440. }
  54441. /**
  54442. * Returns a string representation of the constraint.
  54443. */
  54444. public function toString(): string
  54445. {
  54446. return 'ends with "' . $this->suffix . '"';
  54447. }
  54448. /**
  54449. * Evaluates the constraint for parameter $other. Returns true if the
  54450. * constraint is met, false otherwise.
  54451. */
  54452. protected function matches(mixed $other): bool
  54453. {
  54454. return str_ends_with((string) $other, $this->suffix);
  54455. }
  54456. }
  54457. <?php
  54458. declare (strict_types=1);
  54459. /*
  54460. * This file is part of PHPUnit.
  54461. *
  54462. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54463. *
  54464. * For the full copyright and license information, please view the LICENSE
  54465. * file that was distributed with this source code.
  54466. */
  54467. namespace PHPUnit\Framework\Constraint;
  54468. use function sprintf;
  54469. use function strtr;
  54470. /**
  54471. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54472. */
  54473. final class StringEqualsStringIgnoringLineEndings extends \PHPUnit\Framework\Constraint\Constraint
  54474. {
  54475. private readonly string $string;
  54476. public function __construct(string $string)
  54477. {
  54478. $this->string = $this->normalizeLineEndings($string);
  54479. }
  54480. /**
  54481. * Returns a string representation of the constraint.
  54482. */
  54483. public function toString(): string
  54484. {
  54485. return sprintf('is equal to "%s" ignoring line endings', $this->string);
  54486. }
  54487. /**
  54488. * Evaluates the constraint for parameter $other. Returns true if the
  54489. * constraint is met, false otherwise.
  54490. */
  54491. protected function matches(mixed $other): bool
  54492. {
  54493. return $this->string === $this->normalizeLineEndings((string) $other);
  54494. }
  54495. private function normalizeLineEndings(string $string): string
  54496. {
  54497. return strtr($string, ["\r\n" => "\n", "\r" => "\n"]);
  54498. }
  54499. }
  54500. <?php
  54501. declare (strict_types=1);
  54502. /*
  54503. * This file is part of PHPUnit.
  54504. *
  54505. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54506. *
  54507. * For the full copyright and license information, please view the LICENSE
  54508. * file that was distributed with this source code.
  54509. */
  54510. namespace PHPUnit\Framework\Constraint;
  54511. use const DIRECTORY_SEPARATOR;
  54512. use const PHP_EOL;
  54513. use function explode;
  54514. use function implode;
  54515. use function preg_match;
  54516. use function preg_quote;
  54517. use function preg_replace;
  54518. use function strtr;
  54519. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  54520. use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
  54521. /**
  54522. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54523. */
  54524. final class StringMatchesFormatDescription extends \PHPUnit\Framework\Constraint\Constraint
  54525. {
  54526. private readonly string $formatDescription;
  54527. public function __construct(string $formatDescription)
  54528. {
  54529. $this->formatDescription = $formatDescription;
  54530. }
  54531. public function toString(): string
  54532. {
  54533. return 'matches format description:' . PHP_EOL . $this->formatDescription;
  54534. }
  54535. /**
  54536. * Evaluates the constraint for parameter $other. Returns true if the
  54537. * constraint is met, false otherwise.
  54538. */
  54539. protected function matches(mixed $other): bool
  54540. {
  54541. $other = $this->convertNewlines($other);
  54542. $matches = preg_match($this->regularExpressionForFormatDescription($this->convertNewlines($this->formatDescription)), $other);
  54543. return $matches > 0;
  54544. }
  54545. protected function failureDescription(mixed $other): string
  54546. {
  54547. return 'string matches format description';
  54548. }
  54549. protected function additionalFailureDescription(mixed $other): string
  54550. {
  54551. $from = explode("\n", $this->formatDescription);
  54552. $to = explode("\n", $this->convertNewlines($other));
  54553. foreach ($from as $index => $line) {
  54554. if (isset($to[$index]) && $line !== $to[$index]) {
  54555. $line = $this->regularExpressionForFormatDescription($line);
  54556. if (preg_match($line, $to[$index]) > 0) {
  54557. $from[$index] = $to[$index];
  54558. }
  54559. }
  54560. }
  54561. $from = implode("\n", $from);
  54562. $to = implode("\n", $to);
  54563. return $this->differ()->diff($from, $to);
  54564. }
  54565. private function regularExpressionForFormatDescription(string $string): string
  54566. {
  54567. $string = strtr(preg_quote($string, '/'), ['%%' => '%', '%e' => preg_quote(DIRECTORY_SEPARATOR, '/'), '%s' => '[^\r\n]+', '%S' => '[^\r\n]*', '%a' => '.+?', '%A' => '.*?', '%w' => '\s*', '%i' => '[+-]?\d+', '%d' => '\d+', '%x' => '[0-9a-fA-F]+', '%f' => '[+-]?(?:\d+|(?=\.\d))(?:\.\d+)?(?:[Ee][+-]?\d+)?', '%c' => '.', '%0' => '\x00']);
  54568. return '/^' . $string . '$/s';
  54569. }
  54570. private function convertNewlines(string $text): string
  54571. {
  54572. return preg_replace('/\r\n/', "\n", $text);
  54573. }
  54574. private function differ(): Differ
  54575. {
  54576. return new Differ(new UnifiedDiffOutputBuilder("--- Expected\n+++ Actual\n"));
  54577. }
  54578. }
  54579. <?php
  54580. declare (strict_types=1);
  54581. /*
  54582. * This file is part of PHPUnit.
  54583. *
  54584. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54585. *
  54586. * For the full copyright and license information, please view the LICENSE
  54587. * file that was distributed with this source code.
  54588. */
  54589. namespace PHPUnit\Framework\Constraint;
  54590. use function str_starts_with;
  54591. use PHPUnit\Framework\EmptyStringException;
  54592. /**
  54593. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54594. */
  54595. final class StringStartsWith extends \PHPUnit\Framework\Constraint\Constraint
  54596. {
  54597. private readonly string $prefix;
  54598. /**
  54599. * @throws EmptyStringException
  54600. */
  54601. public function __construct(string $prefix)
  54602. {
  54603. if ($prefix === '') {
  54604. throw new EmptyStringException();
  54605. }
  54606. $this->prefix = $prefix;
  54607. }
  54608. /**
  54609. * Returns a string representation of the constraint.
  54610. */
  54611. public function toString(): string
  54612. {
  54613. return 'starts with "' . $this->prefix . '"';
  54614. }
  54615. /**
  54616. * Evaluates the constraint for parameter $other. Returns true if the
  54617. * constraint is met, false otherwise.
  54618. */
  54619. protected function matches(mixed $other): bool
  54620. {
  54621. return str_starts_with((string) $other, $this->prefix);
  54622. }
  54623. }
  54624. <?php
  54625. declare (strict_types=1);
  54626. /*
  54627. * This file is part of PHPUnit.
  54628. *
  54629. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54630. *
  54631. * For the full copyright and license information, please view the LICENSE
  54632. * file that was distributed with this source code.
  54633. */
  54634. namespace PHPUnit\Framework\Constraint;
  54635. use function array_key_exists;
  54636. use function is_array;
  54637. use ArrayAccess;
  54638. use PHPUnit\Util\Exporter;
  54639. /**
  54640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54641. */
  54642. final class ArrayHasKey extends \PHPUnit\Framework\Constraint\Constraint
  54643. {
  54644. private readonly mixed $key;
  54645. public function __construct(mixed $key)
  54646. {
  54647. $this->key = $key;
  54648. }
  54649. /**
  54650. * Returns a string representation of the constraint.
  54651. */
  54652. public function toString(): string
  54653. {
  54654. return 'has the key ' . Exporter::export($this->key);
  54655. }
  54656. /**
  54657. * Evaluates the constraint for parameter $other. Returns true if the
  54658. * constraint is met, false otherwise.
  54659. */
  54660. protected function matches(mixed $other): bool
  54661. {
  54662. if (is_array($other)) {
  54663. return array_key_exists($this->key, $other);
  54664. }
  54665. if ($other instanceof ArrayAccess) {
  54666. return $other->offsetExists($this->key);
  54667. }
  54668. return \false;
  54669. }
  54670. /**
  54671. * Returns the description of the failure.
  54672. *
  54673. * The beginning of failure messages is "Failed asserting that" in most
  54674. * cases. This method should return the second part of that sentence.
  54675. */
  54676. protected function failureDescription(mixed $other): string
  54677. {
  54678. return 'an array ' . $this->toString(\true);
  54679. }
  54680. }
  54681. <?php
  54682. declare (strict_types=1);
  54683. /*
  54684. * This file is part of PHPUnit.
  54685. *
  54686. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54687. *
  54688. * For the full copyright and license information, please view the LICENSE
  54689. * file that was distributed with this source code.
  54690. */
  54691. namespace PHPUnit\Framework\Constraint;
  54692. use function array_is_list;
  54693. use function is_array;
  54694. /**
  54695. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54696. */
  54697. final class IsList extends \PHPUnit\Framework\Constraint\Constraint
  54698. {
  54699. /**
  54700. * Returns a string representation of the constraint.
  54701. */
  54702. public function toString(): string
  54703. {
  54704. return 'is a list';
  54705. }
  54706. /**
  54707. * Evaluates the constraint for parameter $other. Returns true if the
  54708. * constraint is met, false otherwise.
  54709. */
  54710. protected function matches(mixed $other): bool
  54711. {
  54712. if (!is_array($other)) {
  54713. return \false;
  54714. }
  54715. return array_is_list($other);
  54716. }
  54717. /**
  54718. * Returns the description of the failure.
  54719. *
  54720. * The beginning of failure messages is "Failed asserting that" in most
  54721. * cases. This method should return the second part of that sentence.
  54722. */
  54723. protected function failureDescription(mixed $other): string
  54724. {
  54725. return $this->valueToTypeStringFragment($other) . $this->toString(\true);
  54726. }
  54727. }
  54728. <?php
  54729. declare (strict_types=1);
  54730. /*
  54731. * This file is part of PHPUnit.
  54732. *
  54733. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54734. *
  54735. * For the full copyright and license information, please view the LICENSE
  54736. * file that was distributed with this source code.
  54737. */
  54738. namespace PHPUnit\Framework\Constraint;
  54739. use function is_array;
  54740. use function sprintf;
  54741. use PHPUnit\Util\Exporter;
  54742. /**
  54743. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54744. */
  54745. abstract class TraversableContains extends \PHPUnit\Framework\Constraint\Constraint
  54746. {
  54747. private readonly mixed $value;
  54748. public function __construct(mixed $value)
  54749. {
  54750. $this->value = $value;
  54751. }
  54752. /**
  54753. * Returns a string representation of the constraint.
  54754. */
  54755. public function toString(bool $exportObjects = \false): string
  54756. {
  54757. return 'contains ' . Exporter::export($this->value, $exportObjects);
  54758. }
  54759. /**
  54760. * Returns the description of the failure.
  54761. *
  54762. * The beginning of failure messages is "Failed asserting that" in most
  54763. * cases. This method should return the second part of that sentence.
  54764. */
  54765. protected function failureDescription(mixed $other): string
  54766. {
  54767. return sprintf('%s %s', is_array($other) ? 'an array' : 'a traversable', $this->toString(\true));
  54768. }
  54769. protected function value(): mixed
  54770. {
  54771. return $this->value;
  54772. }
  54773. }
  54774. <?php
  54775. declare (strict_types=1);
  54776. /*
  54777. * This file is part of PHPUnit.
  54778. *
  54779. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54780. *
  54781. * For the full copyright and license information, please view the LICENSE
  54782. * file that was distributed with this source code.
  54783. */
  54784. namespace PHPUnit\Framework\Constraint;
  54785. use SplObjectStorage;
  54786. /**
  54787. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54788. */
  54789. final class TraversableContainsEqual extends \PHPUnit\Framework\Constraint\TraversableContains
  54790. {
  54791. /**
  54792. * Evaluates the constraint for parameter $other. Returns true if the
  54793. * constraint is met, false otherwise.
  54794. */
  54795. protected function matches(mixed $other): bool
  54796. {
  54797. if ($other instanceof SplObjectStorage) {
  54798. return $other->contains($this->value());
  54799. }
  54800. foreach ($other as $element) {
  54801. /* @noinspection TypeUnsafeComparisonInspection */
  54802. if ($this->value() == $element) {
  54803. return \true;
  54804. }
  54805. }
  54806. return \false;
  54807. }
  54808. }
  54809. <?php
  54810. declare (strict_types=1);
  54811. /*
  54812. * This file is part of PHPUnit.
  54813. *
  54814. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54815. *
  54816. * For the full copyright and license information, please view the LICENSE
  54817. * file that was distributed with this source code.
  54818. */
  54819. namespace PHPUnit\Framework\Constraint;
  54820. use SplObjectStorage;
  54821. /**
  54822. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54823. */
  54824. final class TraversableContainsIdentical extends \PHPUnit\Framework\Constraint\TraversableContains
  54825. {
  54826. /**
  54827. * Evaluates the constraint for parameter $other. Returns true if the
  54828. * constraint is met, false otherwise.
  54829. */
  54830. protected function matches(mixed $other): bool
  54831. {
  54832. if ($other instanceof SplObjectStorage) {
  54833. return $other->contains($this->value());
  54834. }
  54835. foreach ($other as $element) {
  54836. if ($this->value() === $element) {
  54837. return \true;
  54838. }
  54839. }
  54840. return \false;
  54841. }
  54842. }
  54843. <?php
  54844. declare (strict_types=1);
  54845. /*
  54846. * This file is part of PHPUnit.
  54847. *
  54848. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54849. *
  54850. * For the full copyright and license information, please view the LICENSE
  54851. * file that was distributed with this source code.
  54852. */
  54853. namespace PHPUnit\Framework\Constraint;
  54854. use PHPUnit\Framework\Exception;
  54855. use PHPUnit\Framework\ExpectationFailedException;
  54856. /**
  54857. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54858. */
  54859. final class TraversableContainsOnly extends \PHPUnit\Framework\Constraint\Constraint
  54860. {
  54861. private \PHPUnit\Framework\Constraint\Constraint $constraint;
  54862. private readonly string $type;
  54863. /**
  54864. * @throws Exception
  54865. */
  54866. public function __construct(string $type, bool $isNativeType = \true)
  54867. {
  54868. if ($isNativeType) {
  54869. $this->constraint = new \PHPUnit\Framework\Constraint\IsType($type);
  54870. } else {
  54871. $this->constraint = new \PHPUnit\Framework\Constraint\IsInstanceOf($type);
  54872. }
  54873. $this->type = $type;
  54874. }
  54875. /**
  54876. * Evaluates the constraint for parameter $other.
  54877. *
  54878. * If $returnResult is set to false (the default), an exception is thrown
  54879. * in case of a failure. null is returned otherwise.
  54880. *
  54881. * If $returnResult is true, the result of the evaluation is returned as
  54882. * a boolean value instead: true in case of success, false in case of a
  54883. * failure.
  54884. *
  54885. * @throws ExpectationFailedException
  54886. */
  54887. public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): bool
  54888. {
  54889. $success = \true;
  54890. foreach ($other as $item) {
  54891. if (!$this->constraint->evaluate($item, '', \true)) {
  54892. $success = \false;
  54893. break;
  54894. }
  54895. }
  54896. if (!$success && !$returnResult) {
  54897. $this->fail($other, $description);
  54898. }
  54899. return $success;
  54900. }
  54901. /**
  54902. * Returns a string representation of the constraint.
  54903. */
  54904. public function toString(): string
  54905. {
  54906. return 'contains only values of type "' . $this->type . '"';
  54907. }
  54908. }
  54909. <?php
  54910. declare (strict_types=1);
  54911. /*
  54912. * This file is part of PHPUnit.
  54913. *
  54914. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54915. *
  54916. * For the full copyright and license information, please view the LICENSE
  54917. * file that was distributed with this source code.
  54918. */
  54919. namespace PHPUnit\Framework\Constraint;
  54920. use function class_exists;
  54921. use function interface_exists;
  54922. use function sprintf;
  54923. use PHPUnit\Framework\UnknownClassOrInterfaceException;
  54924. /**
  54925. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54926. */
  54927. final class IsInstanceOf extends \PHPUnit\Framework\Constraint\Constraint
  54928. {
  54929. /**
  54930. * @psalm-var class-string
  54931. */
  54932. private readonly string $name;
  54933. /**
  54934. * @psalm-var 'class'|'interface'
  54935. */
  54936. private readonly string $type;
  54937. /**
  54938. * @throws UnknownClassOrInterfaceException
  54939. */
  54940. public function __construct(string $name)
  54941. {
  54942. if (class_exists($name)) {
  54943. $this->type = 'class';
  54944. } elseif (interface_exists($name)) {
  54945. $this->type = 'interface';
  54946. } else {
  54947. throw new UnknownClassOrInterfaceException($name);
  54948. }
  54949. $this->name = $name;
  54950. }
  54951. /**
  54952. * Returns a string representation of the constraint.
  54953. */
  54954. public function toString(): string
  54955. {
  54956. return sprintf('is an instance of %s %s', $this->type, $this->name);
  54957. }
  54958. /**
  54959. * Evaluates the constraint for parameter $other. Returns true if the
  54960. * constraint is met, false otherwise.
  54961. */
  54962. protected function matches(mixed $other): bool
  54963. {
  54964. return $other instanceof $this->name;
  54965. }
  54966. /**
  54967. * Returns the description of the failure.
  54968. *
  54969. * The beginning of failure messages is "Failed asserting that" in most
  54970. * cases. This method should return the second part of that sentence.
  54971. */
  54972. protected function failureDescription(mixed $other): string
  54973. {
  54974. return $this->valueToTypeStringFragment($other) . $this->toString(\true);
  54975. }
  54976. }
  54977. <?php
  54978. declare (strict_types=1);
  54979. /*
  54980. * This file is part of PHPUnit.
  54981. *
  54982. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54983. *
  54984. * For the full copyright and license information, please view the LICENSE
  54985. * file that was distributed with this source code.
  54986. */
  54987. namespace PHPUnit\Framework\Constraint;
  54988. /**
  54989. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  54990. */
  54991. final class IsNull extends \PHPUnit\Framework\Constraint\Constraint
  54992. {
  54993. /**
  54994. * Returns a string representation of the constraint.
  54995. */
  54996. public function toString(): string
  54997. {
  54998. return 'is null';
  54999. }
  55000. /**
  55001. * Evaluates the constraint for parameter $other. Returns true if the
  55002. * constraint is met, false otherwise.
  55003. */
  55004. protected function matches(mixed $other): bool
  55005. {
  55006. return $other === null;
  55007. }
  55008. }
  55009. <?php
  55010. declare (strict_types=1);
  55011. /*
  55012. * This file is part of PHPUnit.
  55013. *
  55014. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55015. *
  55016. * For the full copyright and license information, please view the LICENSE
  55017. * file that was distributed with this source code.
  55018. */
  55019. namespace PHPUnit\Framework\Constraint;
  55020. use function gettype;
  55021. use function is_array;
  55022. use function is_bool;
  55023. use function is_callable;
  55024. use function is_float;
  55025. use function is_int;
  55026. use function is_iterable;
  55027. use function is_numeric;
  55028. use function is_object;
  55029. use function is_scalar;
  55030. use function is_string;
  55031. use function sprintf;
  55032. use PHPUnit\Framework\UnknownTypeException;
  55033. /**
  55034. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55035. */
  55036. final class IsType extends \PHPUnit\Framework\Constraint\Constraint
  55037. {
  55038. /**
  55039. * @var string
  55040. */
  55041. public const TYPE_ARRAY = 'array';
  55042. /**
  55043. * @var string
  55044. */
  55045. public const TYPE_BOOL = 'bool';
  55046. /**
  55047. * @var string
  55048. */
  55049. public const TYPE_FLOAT = 'float';
  55050. /**
  55051. * @var string
  55052. */
  55053. public const TYPE_INT = 'int';
  55054. /**
  55055. * @var string
  55056. */
  55057. public const TYPE_NULL = 'null';
  55058. /**
  55059. * @var string
  55060. */
  55061. public const TYPE_NUMERIC = 'numeric';
  55062. /**
  55063. * @var string
  55064. */
  55065. public const TYPE_OBJECT = 'object';
  55066. /**
  55067. * @var string
  55068. */
  55069. public const TYPE_RESOURCE = 'resource';
  55070. /**
  55071. * @var string
  55072. */
  55073. public const TYPE_CLOSED_RESOURCE = 'resource (closed)';
  55074. /**
  55075. * @var string
  55076. */
  55077. public const TYPE_STRING = 'string';
  55078. /**
  55079. * @var string
  55080. */
  55081. public const TYPE_SCALAR = 'scalar';
  55082. /**
  55083. * @var string
  55084. */
  55085. public const TYPE_CALLABLE = 'callable';
  55086. /**
  55087. * @var string
  55088. */
  55089. public const TYPE_ITERABLE = 'iterable';
  55090. /**
  55091. * @psalm-var array<string,bool>
  55092. */
  55093. private const KNOWN_TYPES = ['array' => \true, 'boolean' => \true, 'bool' => \true, 'double' => \true, 'float' => \true, 'integer' => \true, 'int' => \true, 'null' => \true, 'numeric' => \true, 'object' => \true, 'real' => \true, 'resource' => \true, 'resource (closed)' => \true, 'string' => \true, 'scalar' => \true, 'callable' => \true, 'iterable' => \true];
  55094. /**
  55095. * @psalm-var 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable'
  55096. */
  55097. private readonly string $type;
  55098. /**
  55099. * @psalm-param 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' $type
  55100. *
  55101. * @throws UnknownTypeException
  55102. */
  55103. public function __construct(string $type)
  55104. {
  55105. if (!isset(self::KNOWN_TYPES[$type])) {
  55106. throw new UnknownTypeException($type);
  55107. }
  55108. $this->type = $type;
  55109. }
  55110. /**
  55111. * Returns a string representation of the constraint.
  55112. */
  55113. public function toString(): string
  55114. {
  55115. return sprintf('is of type %s', $this->type);
  55116. }
  55117. /**
  55118. * Evaluates the constraint for parameter $other. Returns true if the
  55119. * constraint is met, false otherwise.
  55120. */
  55121. protected function matches(mixed $other): bool
  55122. {
  55123. switch ($this->type) {
  55124. case 'numeric':
  55125. return is_numeric($other);
  55126. case 'integer':
  55127. case 'int':
  55128. return is_int($other);
  55129. case 'double':
  55130. case 'float':
  55131. case 'real':
  55132. return is_float($other);
  55133. case 'string':
  55134. return is_string($other);
  55135. case 'boolean':
  55136. case 'bool':
  55137. return is_bool($other);
  55138. case 'null':
  55139. return null === $other;
  55140. case 'array':
  55141. return is_array($other);
  55142. case 'object':
  55143. return is_object($other);
  55144. case 'resource':
  55145. $type = gettype($other);
  55146. return $type === 'resource' || $type === 'resource (closed)';
  55147. case 'resource (closed)':
  55148. return gettype($other) === 'resource (closed)';
  55149. case 'scalar':
  55150. return is_scalar($other);
  55151. case 'callable':
  55152. return is_callable($other);
  55153. case 'iterable':
  55154. return is_iterable($other);
  55155. default:
  55156. return \false;
  55157. }
  55158. }
  55159. }
  55160. <?php
  55161. declare (strict_types=1);
  55162. /*
  55163. * This file is part of PHPUnit.
  55164. *
  55165. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55166. *
  55167. * For the full copyright and license information, please view the LICENSE
  55168. * file that was distributed with this source code.
  55169. */
  55170. namespace PHPUnit\Framework;
  55171. use function explode;
  55172. use PHPUnit\Framework\TestSize\TestSize;
  55173. use PHPUnit\Metadata\Api\Groups;
  55174. /**
  55175. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55176. *
  55177. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55178. */
  55179. final class DataProviderTestSuite extends \PHPUnit\Framework\TestSuite
  55180. {
  55181. /**
  55182. * @psalm-var list<ExecutionOrderDependency>
  55183. */
  55184. private array $dependencies = [];
  55185. private ?array $providedTests = null;
  55186. /**
  55187. * @psalm-param list<ExecutionOrderDependency> $dependencies
  55188. */
  55189. public function setDependencies(array $dependencies): void
  55190. {
  55191. $this->dependencies = $dependencies;
  55192. foreach ($this->tests() as $test) {
  55193. if (!$test instanceof \PHPUnit\Framework\TestCase) {
  55194. continue;
  55195. }
  55196. $test->setDependencies($dependencies);
  55197. }
  55198. }
  55199. /**
  55200. * @psalm-return list<ExecutionOrderDependency>
  55201. */
  55202. public function provides(): array
  55203. {
  55204. if ($this->providedTests === null) {
  55205. $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->name())];
  55206. }
  55207. return $this->providedTests;
  55208. }
  55209. /**
  55210. * @psalm-return list<ExecutionOrderDependency>
  55211. */
  55212. public function requires(): array
  55213. {
  55214. // A DataProviderTestSuite does not have to traverse its child tests
  55215. // as these are inherited and cannot reference dataProvider rows directly
  55216. return $this->dependencies;
  55217. }
  55218. /**
  55219. * Returns the size of each test created using the data provider(s).
  55220. */
  55221. public function size(): TestSize
  55222. {
  55223. [$className, $methodName] = explode('::', $this->name());
  55224. return (new Groups())->size($className, $methodName);
  55225. }
  55226. }
  55227. <?php
  55228. declare (strict_types=1);
  55229. /*
  55230. * This file is part of PHPUnit.
  55231. *
  55232. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55233. *
  55234. * For the full copyright and license information, please view the LICENSE
  55235. * file that was distributed with this source code.
  55236. */
  55237. namespace PHPUnit\Framework;
  55238. /**
  55239. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55240. *
  55241. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55242. */
  55243. class AssertionFailedError extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\SelfDescribing
  55244. {
  55245. /**
  55246. * Wrapper for getMessage() which is declared as final.
  55247. */
  55248. public function toString(): string
  55249. {
  55250. return $this->getMessage();
  55251. }
  55252. }
  55253. <?php
  55254. declare (strict_types=1);
  55255. /*
  55256. * This file is part of PHPUnit.
  55257. *
  55258. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55259. *
  55260. * For the full copyright and license information, please view the LICENSE
  55261. * file that was distributed with this source code.
  55262. */
  55263. namespace PHPUnit\Framework;
  55264. /**
  55265. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55266. *
  55267. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55268. */
  55269. class CodeCoverageException extends \PHPUnit\Framework\Exception
  55270. {
  55271. }
  55272. <?php
  55273. declare (strict_types=1);
  55274. /*
  55275. * This file is part of PHPUnit.
  55276. *
  55277. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55278. *
  55279. * For the full copyright and license information, please view the LICENSE
  55280. * file that was distributed with this source code.
  55281. */
  55282. namespace PHPUnit\Framework;
  55283. /**
  55284. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55285. *
  55286. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55287. */
  55288. final class EmptyStringException extends \PHPUnit\Framework\InvalidArgumentException
  55289. {
  55290. }
  55291. <?php
  55292. declare (strict_types=1);
  55293. /*
  55294. * This file is part of PHPUnit.
  55295. *
  55296. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55297. *
  55298. * For the full copyright and license information, please view the LICENSE
  55299. * file that was distributed with this source code.
  55300. */
  55301. namespace PHPUnit\Framework;
  55302. use function array_keys;
  55303. use function get_object_vars;
  55304. use function is_int;
  55305. use function sprintf;
  55306. use RuntimeException;
  55307. use Throwable;
  55308. /**
  55309. * Base class for all PHPUnit Framework exceptions.
  55310. *
  55311. * Ensures that exceptions thrown during a test run do not leave stray
  55312. * references behind.
  55313. *
  55314. * Every Exception contains a stack trace. Each stack frame contains the 'args'
  55315. * of the called function. The function arguments can contain references to
  55316. * instantiated objects. The references prevent the objects from being
  55317. * destructed (until test results are eventually printed), so memory cannot be
  55318. * freed up.
  55319. *
  55320. * With enabled process isolation, test results are serialized in the child
  55321. * process and unserialized in the parent process. The stack trace of Exceptions
  55322. * may contain objects that cannot be serialized or unserialized (e.g., PDO
  55323. * connections). Unserializing user-space objects from the child process into
  55324. * the parent would break the intended encapsulation of process isolation.
  55325. *
  55326. * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
  55327. *
  55328. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55329. *
  55330. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55331. */
  55332. class Exception extends RuntimeException implements \PHPUnit\Exception
  55333. {
  55334. protected array $serializableTrace;
  55335. public function __construct(string $message = '', int|string $code = 0, ?Throwable $previous = null)
  55336. {
  55337. /**
  55338. * @see https://github.com/sebastianbergmann/phpunit/issues/5965
  55339. */
  55340. if (!is_int($code)) {
  55341. $message .= sprintf(' (exception code: %s)', $code);
  55342. $code = 0;
  55343. }
  55344. parent::__construct($message, $code, $previous);
  55345. $this->serializableTrace = $this->getTrace();
  55346. foreach (array_keys($this->serializableTrace) as $key) {
  55347. unset($this->serializableTrace[$key]['args']);
  55348. }
  55349. }
  55350. public function __sleep(): array
  55351. {
  55352. return array_keys(get_object_vars($this));
  55353. }
  55354. /**
  55355. * Returns the serializable trace (without 'args').
  55356. */
  55357. public function getSerializableTrace(): array
  55358. {
  55359. return $this->serializableTrace;
  55360. }
  55361. }
  55362. <?php
  55363. declare (strict_types=1);
  55364. /*
  55365. * This file is part of PHPUnit.
  55366. *
  55367. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55368. *
  55369. * For the full copyright and license information, please view the LICENSE
  55370. * file that was distributed with this source code.
  55371. */
  55372. namespace PHPUnit\Framework;
  55373. use Exception;
  55374. use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
  55375. /**
  55376. * Exception for expectations which failed their check.
  55377. *
  55378. * The exception contains the error message and optionally a
  55379. * SebastianBergmann\Comparator\ComparisonFailure which is used to
  55380. * generate diff output of the failed expectations.
  55381. *
  55382. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55383. *
  55384. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55385. */
  55386. final class ExpectationFailedException extends \PHPUnit\Framework\AssertionFailedError
  55387. {
  55388. protected ?ComparisonFailure $comparisonFailure = null;
  55389. public function __construct(string $message, ?ComparisonFailure $comparisonFailure = null, ?Exception $previous = null)
  55390. {
  55391. $this->comparisonFailure = $comparisonFailure;
  55392. parent::__construct($message, 0, $previous);
  55393. }
  55394. public function getComparisonFailure(): ?ComparisonFailure
  55395. {
  55396. return $this->comparisonFailure;
  55397. }
  55398. }
  55399. <?php
  55400. declare (strict_types=1);
  55401. /*
  55402. * This file is part of PHPUnit.
  55403. *
  55404. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55405. *
  55406. * For the full copyright and license information, please view the LICENSE
  55407. * file that was distributed with this source code.
  55408. */
  55409. namespace PHPUnit\Framework;
  55410. use function sprintf;
  55411. /**
  55412. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55413. *
  55414. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55415. */
  55416. final class GeneratorNotSupportedException extends \PHPUnit\Framework\InvalidArgumentException
  55417. {
  55418. public static function fromParameterName(string $parameterName): self
  55419. {
  55420. return new self(sprintf('Passing an argument of type Generator for the %s parameter is not supported', $parameterName));
  55421. }
  55422. }
  55423. <?php
  55424. declare (strict_types=1);
  55425. /*
  55426. * This file is part of PHPUnit.
  55427. *
  55428. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55429. *
  55430. * For the full copyright and license information, please view the LICENSE
  55431. * file that was distributed with this source code.
  55432. */
  55433. namespace PHPUnit\Framework;
  55434. use Throwable;
  55435. /**
  55436. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55437. *
  55438. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55439. */
  55440. interface IncompleteTest extends Throwable
  55441. {
  55442. }
  55443. <?php
  55444. declare (strict_types=1);
  55445. /*
  55446. * This file is part of PHPUnit.
  55447. *
  55448. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55449. *
  55450. * For the full copyright and license information, please view the LICENSE
  55451. * file that was distributed with this source code.
  55452. */
  55453. namespace PHPUnit\Framework;
  55454. /**
  55455. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55456. *
  55457. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55458. */
  55459. final class IncompleteTestError extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\IncompleteTest
  55460. {
  55461. }
  55462. <?php
  55463. declare (strict_types=1);
  55464. /*
  55465. * This file is part of PHPUnit.
  55466. *
  55467. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55468. *
  55469. * For the full copyright and license information, please view the LICENSE
  55470. * file that was distributed with this source code.
  55471. */
  55472. namespace PHPUnit\Framework;
  55473. /**
  55474. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55475. *
  55476. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55477. */
  55478. abstract class InvalidArgumentException extends \PHPUnit\Framework\Exception
  55479. {
  55480. }
  55481. <?php
  55482. declare (strict_types=1);
  55483. /*
  55484. * This file is part of PHPUnit.
  55485. *
  55486. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55487. *
  55488. * For the full copyright and license information, please view the LICENSE
  55489. * file that was distributed with this source code.
  55490. */
  55491. namespace PHPUnit\Framework;
  55492. /**
  55493. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55494. *
  55495. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55496. */
  55497. final class InvalidCoversTargetException extends \PHPUnit\Framework\CodeCoverageException
  55498. {
  55499. }
  55500. <?php
  55501. declare (strict_types=1);
  55502. /*
  55503. * This file is part of PHPUnit.
  55504. *
  55505. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55506. *
  55507. * For the full copyright and license information, please view the LICENSE
  55508. * file that was distributed with this source code.
  55509. */
  55510. namespace PHPUnit\Framework;
  55511. /**
  55512. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55513. *
  55514. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55515. */
  55516. final class InvalidDataProviderException extends \PHPUnit\Framework\Exception
  55517. {
  55518. }
  55519. <?php
  55520. declare (strict_types=1);
  55521. /*
  55522. * This file is part of PHPUnit.
  55523. *
  55524. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55525. *
  55526. * For the full copyright and license information, please view the LICENSE
  55527. * file that was distributed with this source code.
  55528. */
  55529. namespace PHPUnit\Framework;
  55530. /**
  55531. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55532. *
  55533. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55534. */
  55535. final class InvalidDependencyException extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
  55536. {
  55537. }
  55538. <?php
  55539. declare (strict_types=1);
  55540. /*
  55541. * This file is part of PHPUnit.
  55542. *
  55543. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55544. *
  55545. * For the full copyright and license information, please view the LICENSE
  55546. * file that was distributed with this source code.
  55547. */
  55548. namespace PHPUnit\Framework;
  55549. /**
  55550. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55551. *
  55552. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55553. */
  55554. final class NoChildTestSuiteException extends \PHPUnit\Framework\Exception
  55555. {
  55556. }
  55557. <?php
  55558. declare (strict_types=1);
  55559. /*
  55560. * This file is part of PHPUnit.
  55561. *
  55562. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55563. *
  55564. * For the full copyright and license information, please view the LICENSE
  55565. * file that was distributed with this source code.
  55566. */
  55567. namespace PHPUnit\Framework;
  55568. /**
  55569. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55570. *
  55571. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55572. */
  55573. final class ActualValueIsNotAnObjectException extends \PHPUnit\Framework\Exception
  55574. {
  55575. public function __construct()
  55576. {
  55577. parent::__construct('Actual value is not an object');
  55578. }
  55579. }
  55580. <?php
  55581. declare (strict_types=1);
  55582. /*
  55583. * This file is part of PHPUnit.
  55584. *
  55585. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55586. *
  55587. * For the full copyright and license information, please view the LICENSE
  55588. * file that was distributed with this source code.
  55589. */
  55590. namespace PHPUnit\Framework;
  55591. use function sprintf;
  55592. /**
  55593. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55594. *
  55595. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55596. */
  55597. final class ComparisonMethodDoesNotAcceptParameterTypeException extends \PHPUnit\Framework\Exception
  55598. {
  55599. public function __construct(string $className, string $methodName, string $type)
  55600. {
  55601. parent::__construct(sprintf('%s is not an accepted argument type for comparison method %s::%s().', $type, $className, $methodName));
  55602. }
  55603. }
  55604. <?php
  55605. declare (strict_types=1);
  55606. /*
  55607. * This file is part of PHPUnit.
  55608. *
  55609. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55610. *
  55611. * For the full copyright and license information, please view the LICENSE
  55612. * file that was distributed with this source code.
  55613. */
  55614. namespace PHPUnit\Framework;
  55615. use function sprintf;
  55616. /**
  55617. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55618. *
  55619. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55620. */
  55621. final class ComparisonMethodDoesNotDeclareBoolReturnTypeException extends \PHPUnit\Framework\Exception
  55622. {
  55623. public function __construct(string $className, string $methodName)
  55624. {
  55625. parent::__construct(sprintf('Comparison method %s::%s() does not declare bool return type.', $className, $methodName));
  55626. }
  55627. }
  55628. <?php
  55629. declare (strict_types=1);
  55630. /*
  55631. * This file is part of PHPUnit.
  55632. *
  55633. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55634. *
  55635. * For the full copyright and license information, please view the LICENSE
  55636. * file that was distributed with this source code.
  55637. */
  55638. namespace PHPUnit\Framework;
  55639. use function sprintf;
  55640. /**
  55641. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55642. *
  55643. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55644. */
  55645. final class ComparisonMethodDoesNotDeclareExactlyOneParameterException extends \PHPUnit\Framework\Exception
  55646. {
  55647. public function __construct(string $className, string $methodName)
  55648. {
  55649. parent::__construct(sprintf('Comparison method %s::%s() does not declare exactly one parameter.', $className, $methodName));
  55650. }
  55651. }
  55652. <?php
  55653. declare (strict_types=1);
  55654. /*
  55655. * This file is part of PHPUnit.
  55656. *
  55657. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55658. *
  55659. * For the full copyright and license information, please view the LICENSE
  55660. * file that was distributed with this source code.
  55661. */
  55662. namespace PHPUnit\Framework;
  55663. use function sprintf;
  55664. /**
  55665. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55666. *
  55667. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55668. */
  55669. final class ComparisonMethodDoesNotDeclareParameterTypeException extends \PHPUnit\Framework\Exception
  55670. {
  55671. public function __construct(string $className, string $methodName)
  55672. {
  55673. parent::__construct(sprintf('Parameter of comparison method %s::%s() does not have a declared type.', $className, $methodName));
  55674. }
  55675. }
  55676. <?php
  55677. declare (strict_types=1);
  55678. /*
  55679. * This file is part of PHPUnit.
  55680. *
  55681. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55682. *
  55683. * For the full copyright and license information, please view the LICENSE
  55684. * file that was distributed with this source code.
  55685. */
  55686. namespace PHPUnit\Framework;
  55687. use function sprintf;
  55688. /**
  55689. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55690. *
  55691. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55692. */
  55693. final class ComparisonMethodDoesNotExistException extends \PHPUnit\Framework\Exception
  55694. {
  55695. public function __construct(string $className, string $methodName)
  55696. {
  55697. parent::__construct(sprintf('Comparison method %s::%s() does not exist.', $className, $methodName));
  55698. }
  55699. }
  55700. <?php
  55701. declare (strict_types=1);
  55702. /*
  55703. * This file is part of PHPUnit.
  55704. *
  55705. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55706. *
  55707. * For the full copyright and license information, please view the LICENSE
  55708. * file that was distributed with this source code.
  55709. */
  55710. namespace PHPUnit\Framework;
  55711. /**
  55712. * @psalm-immutable
  55713. *
  55714. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55715. *
  55716. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55717. */
  55718. final class PhptAssertionFailedError extends \PHPUnit\Framework\AssertionFailedError
  55719. {
  55720. private readonly string $syntheticFile;
  55721. private readonly int $syntheticLine;
  55722. private readonly array $syntheticTrace;
  55723. private readonly string $diff;
  55724. public function __construct(string $message, int $code, string $file, int $line, array $trace, string $diff)
  55725. {
  55726. parent::__construct($message, $code);
  55727. $this->syntheticFile = $file;
  55728. $this->syntheticLine = $line;
  55729. $this->syntheticTrace = $trace;
  55730. $this->diff = $diff;
  55731. }
  55732. public function syntheticFile(): string
  55733. {
  55734. return $this->syntheticFile;
  55735. }
  55736. public function syntheticLine(): int
  55737. {
  55738. return $this->syntheticLine;
  55739. }
  55740. public function syntheticTrace(): array
  55741. {
  55742. return $this->syntheticTrace;
  55743. }
  55744. public function diff(): string
  55745. {
  55746. return $this->diff;
  55747. }
  55748. }
  55749. <?php
  55750. declare (strict_types=1);
  55751. /*
  55752. * This file is part of PHPUnit.
  55753. *
  55754. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55755. *
  55756. * For the full copyright and license information, please view the LICENSE
  55757. * file that was distributed with this source code.
  55758. */
  55759. namespace PHPUnit\Framework;
  55760. /**
  55761. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55762. *
  55763. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55764. */
  55765. final class ProcessIsolationException extends \PHPUnit\Framework\Exception
  55766. {
  55767. }
  55768. <?php
  55769. declare (strict_types=1);
  55770. /*
  55771. * This file is part of PHPUnit.
  55772. *
  55773. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55774. *
  55775. * For the full copyright and license information, please view the LICENSE
  55776. * file that was distributed with this source code.
  55777. */
  55778. namespace PHPUnit\Framework;
  55779. use Throwable;
  55780. /**
  55781. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55782. *
  55783. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55784. */
  55785. interface SkippedTest extends Throwable
  55786. {
  55787. }
  55788. <?php
  55789. declare (strict_types=1);
  55790. /*
  55791. * This file is part of PHPUnit.
  55792. *
  55793. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55794. *
  55795. * For the full copyright and license information, please view the LICENSE
  55796. * file that was distributed with this source code.
  55797. */
  55798. namespace PHPUnit\Framework;
  55799. /**
  55800. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55801. *
  55802. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55803. */
  55804. final class SkippedTestSuiteError extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
  55805. {
  55806. }
  55807. <?php
  55808. declare (strict_types=1);
  55809. /*
  55810. * This file is part of PHPUnit.
  55811. *
  55812. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55813. *
  55814. * For the full copyright and license information, please view the LICENSE
  55815. * file that was distributed with this source code.
  55816. */
  55817. namespace PHPUnit\Framework;
  55818. /**
  55819. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55820. *
  55821. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55822. */
  55823. final class SkippedWithMessageException extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
  55824. {
  55825. }
  55826. <?php
  55827. declare (strict_types=1);
  55828. /*
  55829. * This file is part of PHPUnit.
  55830. *
  55831. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55832. *
  55833. * For the full copyright and license information, please view the LICENSE
  55834. * file that was distributed with this source code.
  55835. */
  55836. namespace PHPUnit\Framework;
  55837. use function sprintf;
  55838. /**
  55839. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55840. *
  55841. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55842. */
  55843. final class UnknownClassOrInterfaceException extends \PHPUnit\Framework\InvalidArgumentException
  55844. {
  55845. public function __construct(string $name)
  55846. {
  55847. parent::__construct(sprintf('Class or interface "%s" does not exist', $name));
  55848. }
  55849. }
  55850. <?php
  55851. declare (strict_types=1);
  55852. /*
  55853. * This file is part of PHPUnit.
  55854. *
  55855. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55856. *
  55857. * For the full copyright and license information, please view the LICENSE
  55858. * file that was distributed with this source code.
  55859. */
  55860. namespace PHPUnit\Framework;
  55861. use function sprintf;
  55862. /**
  55863. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55864. *
  55865. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55866. */
  55867. final class UnknownTypeException extends \PHPUnit\Framework\InvalidArgumentException
  55868. {
  55869. public function __construct(string $name)
  55870. {
  55871. parent::__construct(sprintf('Type "%s" is not known', $name));
  55872. }
  55873. }
  55874. <?php
  55875. declare (strict_types=1);
  55876. /*
  55877. * This file is part of PHPUnit.
  55878. *
  55879. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55880. *
  55881. * For the full copyright and license information, please view the LICENSE
  55882. * file that was distributed with this source code.
  55883. */
  55884. namespace PHPUnit\Framework;
  55885. use function array_filter;
  55886. use function array_map;
  55887. use function array_values;
  55888. use function explode;
  55889. use function in_array;
  55890. use function str_contains;
  55891. use PHPUnit\Metadata\DependsOnClass;
  55892. use PHPUnit\Metadata\DependsOnMethod;
  55893. use Stringable;
  55894. /**
  55895. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  55896. *
  55897. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  55898. */
  55899. final class ExecutionOrderDependency implements Stringable
  55900. {
  55901. private string $className = '';
  55902. private string $methodName = '';
  55903. private readonly bool $shallowClone;
  55904. private readonly bool $deepClone;
  55905. public static function invalid(): self
  55906. {
  55907. return new self('', '', \false, \false);
  55908. }
  55909. public static function forClass(DependsOnClass $metadata): self
  55910. {
  55911. return new self($metadata->className(), 'class', $metadata->deepClone(), $metadata->shallowClone());
  55912. }
  55913. public static function forMethod(DependsOnMethod $metadata): self
  55914. {
  55915. return new self($metadata->className(), $metadata->methodName(), $metadata->deepClone(), $metadata->shallowClone());
  55916. }
  55917. /**
  55918. * @psalm-param list<ExecutionOrderDependency> $dependencies
  55919. *
  55920. * @psalm-return list<ExecutionOrderDependency>
  55921. */
  55922. public static function filterInvalid(array $dependencies): array
  55923. {
  55924. return array_values(array_filter($dependencies, static fn(self $d) => $d->isValid()));
  55925. }
  55926. /**
  55927. * @psalm-param list<ExecutionOrderDependency> $existing
  55928. * @psalm-param list<ExecutionOrderDependency> $additional
  55929. *
  55930. * @psalm-return list<ExecutionOrderDependency>
  55931. */
  55932. public static function mergeUnique(array $existing, array $additional): array
  55933. {
  55934. $existingTargets = array_map(static fn($dependency) => $dependency->getTarget(), $existing);
  55935. foreach ($additional as $dependency) {
  55936. $additionalTarget = $dependency->getTarget();
  55937. if (in_array($additionalTarget, $existingTargets, \true)) {
  55938. continue;
  55939. }
  55940. $existingTargets[] = $additionalTarget;
  55941. $existing[] = $dependency;
  55942. }
  55943. return $existing;
  55944. }
  55945. /**
  55946. * @psalm-param list<ExecutionOrderDependency> $left
  55947. * @psalm-param list<ExecutionOrderDependency> $right
  55948. *
  55949. * @psalm-return list<ExecutionOrderDependency>
  55950. */
  55951. public static function diff(array $left, array $right): array
  55952. {
  55953. if ($right === []) {
  55954. return $left;
  55955. }
  55956. if ($left === []) {
  55957. return [];
  55958. }
  55959. $diff = [];
  55960. $rightTargets = array_map(static fn($dependency) => $dependency->getTarget(), $right);
  55961. foreach ($left as $dependency) {
  55962. if (in_array($dependency->getTarget(), $rightTargets, \true)) {
  55963. continue;
  55964. }
  55965. $diff[] = $dependency;
  55966. }
  55967. return $diff;
  55968. }
  55969. public function __construct(string $classOrCallableName, ?string $methodName = null, bool $deepClone = \false, bool $shallowClone = \false)
  55970. {
  55971. $this->deepClone = $deepClone;
  55972. $this->shallowClone = $shallowClone;
  55973. if ($classOrCallableName === '') {
  55974. return;
  55975. }
  55976. if (str_contains($classOrCallableName, '::')) {
  55977. [$this->className, $this->methodName] = explode('::', $classOrCallableName);
  55978. } else {
  55979. $this->className = $classOrCallableName;
  55980. $this->methodName = !empty($methodName) ? $methodName : 'class';
  55981. }
  55982. }
  55983. public function __toString(): string
  55984. {
  55985. return $this->getTarget();
  55986. }
  55987. public function isValid(): bool
  55988. {
  55989. // Invalid dependencies can be declared and are skipped by the runner
  55990. return $this->className !== '' && $this->methodName !== '';
  55991. }
  55992. public function shallowClone(): bool
  55993. {
  55994. return $this->shallowClone;
  55995. }
  55996. public function deepClone(): bool
  55997. {
  55998. return $this->deepClone;
  55999. }
  56000. public function targetIsClass(): bool
  56001. {
  56002. return $this->methodName === 'class';
  56003. }
  56004. public function getTarget(): string
  56005. {
  56006. return $this->isValid() ? $this->className . '::' . $this->methodName : '';
  56007. }
  56008. public function getTargetClassName(): string
  56009. {
  56010. return $this->className;
  56011. }
  56012. }
  56013. <?php
  56014. declare (strict_types=1);
  56015. /*
  56016. * This file is part of PHPUnit.
  56017. *
  56018. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56019. *
  56020. * For the full copyright and license information, please view the LICENSE
  56021. * file that was distributed with this source code.
  56022. */
  56023. namespace PHPUnit\Framework\MockObject;
  56024. use PHPUnitPHAR\SebastianBergmann\Type\Type;
  56025. /**
  56026. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56027. *
  56028. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56029. */
  56030. final class ConfigurableMethod
  56031. {
  56032. /**
  56033. * @psalm-var non-empty-string
  56034. */
  56035. private readonly string $name;
  56036. /**
  56037. * @psalm-var array<int, mixed>
  56038. */
  56039. private readonly array $defaultParameterValues;
  56040. /**
  56041. * @psalm-var non-negative-int
  56042. */
  56043. private readonly int $numberOfParameters;
  56044. private readonly Type $returnType;
  56045. /**
  56046. * @psalm-param non-empty-string $name
  56047. * @psalm-param array<int, mixed> $defaultParameterValues
  56048. * @psalm-param non-negative-int $numberOfParameters
  56049. */
  56050. public function __construct(string $name, array $defaultParameterValues, int $numberOfParameters, Type $returnType)
  56051. {
  56052. $this->name = $name;
  56053. $this->defaultParameterValues = $defaultParameterValues;
  56054. $this->numberOfParameters = $numberOfParameters;
  56055. $this->returnType = $returnType;
  56056. }
  56057. /**
  56058. * @psalm-return non-empty-string
  56059. */
  56060. public function name(): string
  56061. {
  56062. return $this->name;
  56063. }
  56064. /**
  56065. * @psalm-return array<int, mixed>
  56066. */
  56067. public function defaultParameterValues(): array
  56068. {
  56069. return $this->defaultParameterValues;
  56070. }
  56071. /**
  56072. * @psalm-return non-negative-int
  56073. */
  56074. public function numberOfParameters(): int
  56075. {
  56076. return $this->numberOfParameters;
  56077. }
  56078. public function mayReturn(mixed $value): bool
  56079. {
  56080. return $this->returnType->isAssignable(Type::fromValue($value, \false));
  56081. }
  56082. public function returnTypeDeclaration(): string
  56083. {
  56084. return $this->returnType->asString();
  56085. }
  56086. }
  56087. <?php
  56088. declare (strict_types=1);
  56089. /*
  56090. * This file is part of PHPUnit.
  56091. *
  56092. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56093. *
  56094. * For the full copyright and license information, please view the LICENSE
  56095. * file that was distributed with this source code.
  56096. */
  56097. namespace PHPUnit\Framework\MockObject;
  56098. /**
  56099. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56100. *
  56101. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56102. */
  56103. final class BadMethodCallException extends \BadMethodCallException implements \PHPUnit\Framework\MockObject\Exception
  56104. {
  56105. }
  56106. <?php
  56107. declare (strict_types=1);
  56108. /*
  56109. * This file is part of PHPUnit.
  56110. *
  56111. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56112. *
  56113. * For the full copyright and license information, please view the LICENSE
  56114. * file that was distributed with this source code.
  56115. */
  56116. namespace PHPUnit\Framework\MockObject;
  56117. use function sprintf;
  56118. /**
  56119. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56120. *
  56121. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56122. */
  56123. final class CannotUseOnlyMethodsException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56124. {
  56125. public function __construct(string $type, string $methodName)
  56126. {
  56127. parent::__construct(sprintf('Trying to configure method "%s" with onlyMethods(), but it does not exist in class "%s"', $methodName, $type));
  56128. }
  56129. }
  56130. <?php
  56131. declare (strict_types=1);
  56132. /*
  56133. * This file is part of PHPUnit.
  56134. *
  56135. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56136. *
  56137. * For the full copyright and license information, please view the LICENSE
  56138. * file that was distributed with this source code.
  56139. */
  56140. namespace PHPUnit\Framework\MockObject;
  56141. use Throwable;
  56142. /**
  56143. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56144. *
  56145. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56146. */
  56147. interface Exception extends Throwable
  56148. {
  56149. }
  56150. <?php
  56151. declare (strict_types=1);
  56152. /*
  56153. * This file is part of PHPUnit.
  56154. *
  56155. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56156. *
  56157. * For the full copyright and license information, please view the LICENSE
  56158. * file that was distributed with this source code.
  56159. */
  56160. namespace PHPUnit\Framework\MockObject;
  56161. use function get_debug_type;
  56162. use function sprintf;
  56163. /**
  56164. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56165. *
  56166. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56167. */
  56168. final class IncompatibleReturnValueException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56169. {
  56170. public function __construct(\PHPUnit\Framework\MockObject\ConfigurableMethod $method, mixed $value)
  56171. {
  56172. parent::__construct(sprintf('Method %s may not return value of type %s, its declared return type is "%s"', $method->name(), get_debug_type($value), $method->returnTypeDeclaration()));
  56173. }
  56174. }
  56175. <?php
  56176. declare (strict_types=1);
  56177. /*
  56178. * This file is part of PHPUnit.
  56179. *
  56180. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56181. *
  56182. * For the full copyright and license information, please view the LICENSE
  56183. * file that was distributed with this source code.
  56184. */
  56185. namespace PHPUnit\Framework\MockObject;
  56186. use function sprintf;
  56187. /**
  56188. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56189. *
  56190. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56191. */
  56192. final class MatchBuilderNotFoundException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56193. {
  56194. public function __construct(string $id)
  56195. {
  56196. parent::__construct(sprintf('No builder found for match builder identification <%s>', $id));
  56197. }
  56198. }
  56199. <?php
  56200. declare (strict_types=1);
  56201. /*
  56202. * This file is part of PHPUnit.
  56203. *
  56204. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56205. *
  56206. * For the full copyright and license information, please view the LICENSE
  56207. * file that was distributed with this source code.
  56208. */
  56209. namespace PHPUnit\Framework\MockObject;
  56210. use function sprintf;
  56211. /**
  56212. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56213. *
  56214. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56215. */
  56216. final class MatcherAlreadyRegisteredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56217. {
  56218. public function __construct(string $id)
  56219. {
  56220. parent::__construct(sprintf('Matcher with id <%s> is already registered', $id));
  56221. }
  56222. }
  56223. <?php
  56224. declare (strict_types=1);
  56225. /*
  56226. * This file is part of PHPUnit.
  56227. *
  56228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56229. *
  56230. * For the full copyright and license information, please view the LICENSE
  56231. * file that was distributed with this source code.
  56232. */
  56233. namespace PHPUnit\Framework\MockObject;
  56234. use function sprintf;
  56235. /**
  56236. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56237. *
  56238. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56239. */
  56240. final class MethodCannotBeConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56241. {
  56242. public function __construct(string $method)
  56243. {
  56244. parent::__construct(sprintf('Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static', $method));
  56245. }
  56246. }
  56247. <?php
  56248. declare (strict_types=1);
  56249. /*
  56250. * This file is part of PHPUnit.
  56251. *
  56252. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56253. *
  56254. * For the full copyright and license information, please view the LICENSE
  56255. * file that was distributed with this source code.
  56256. */
  56257. namespace PHPUnit\Framework\MockObject;
  56258. /**
  56259. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56260. *
  56261. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56262. */
  56263. final class MethodNameAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56264. {
  56265. public function __construct()
  56266. {
  56267. parent::__construct('Method name is already configured');
  56268. }
  56269. }
  56270. <?php
  56271. declare (strict_types=1);
  56272. /*
  56273. * This file is part of PHPUnit.
  56274. *
  56275. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56276. *
  56277. * For the full copyright and license information, please view the LICENSE
  56278. * file that was distributed with this source code.
  56279. */
  56280. namespace PHPUnit\Framework\MockObject;
  56281. /**
  56282. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56283. *
  56284. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56285. */
  56286. final class MethodNameNotConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56287. {
  56288. public function __construct()
  56289. {
  56290. parent::__construct('Method name is not configured');
  56291. }
  56292. }
  56293. <?php
  56294. declare (strict_types=1);
  56295. /*
  56296. * This file is part of PHPUnit.
  56297. *
  56298. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56299. *
  56300. * For the full copyright and license information, please view the LICENSE
  56301. * file that was distributed with this source code.
  56302. */
  56303. namespace PHPUnit\Framework\MockObject;
  56304. /**
  56305. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56306. *
  56307. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56308. */
  56309. final class MethodParametersAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56310. {
  56311. public function __construct()
  56312. {
  56313. parent::__construct('Method parameters already configured');
  56314. }
  56315. }
  56316. <?php
  56317. declare (strict_types=1);
  56318. /*
  56319. * This file is part of PHPUnit.
  56320. *
  56321. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56322. *
  56323. * For the full copyright and license information, please view the LICENSE
  56324. * file that was distributed with this source code.
  56325. */
  56326. namespace PHPUnit\Framework\MockObject;
  56327. use function sprintf;
  56328. use RuntimeException;
  56329. /**
  56330. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56331. */
  56332. final class NeverReturningMethodException extends RuntimeException implements \PHPUnit\Framework\MockObject\Exception
  56333. {
  56334. /**
  56335. * @psalm-param class-string $className
  56336. * @psalm-param non-empty-string $methodName
  56337. */
  56338. public function __construct(string $className, string $methodName)
  56339. {
  56340. parent::__construct(sprintf('Method %s::%s() is declared to never return', $className, $methodName));
  56341. }
  56342. }
  56343. <?php
  56344. declare (strict_types=1);
  56345. /*
  56346. * This file is part of PHPUnit.
  56347. *
  56348. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56349. *
  56350. * For the full copyright and license information, please view the LICENSE
  56351. * file that was distributed with this source code.
  56352. */
  56353. namespace PHPUnit\Framework\MockObject;
  56354. use function sprintf;
  56355. /**
  56356. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56357. *
  56358. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56359. */
  56360. final class NoMoreReturnValuesConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56361. {
  56362. public function __construct(\PHPUnit\Framework\MockObject\Invocation $invocation, int $numberOfConfiguredReturnValues)
  56363. {
  56364. parent::__construct(sprintf('Only %d return values have been configured for %s::%s()', $numberOfConfiguredReturnValues, $invocation->className(), $invocation->methodName()));
  56365. }
  56366. }
  56367. <?php
  56368. declare (strict_types=1);
  56369. /*
  56370. * This file is part of PHPUnit.
  56371. *
  56372. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56373. *
  56374. * For the full copyright and license information, please view the LICENSE
  56375. * file that was distributed with this source code.
  56376. */
  56377. namespace PHPUnit\Framework\MockObject;
  56378. use function sprintf;
  56379. /**
  56380. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56381. *
  56382. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56383. */
  56384. final class ReturnValueNotConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
  56385. {
  56386. public function __construct(\PHPUnit\Framework\MockObject\Invocation $invocation)
  56387. {
  56388. parent::__construct(sprintf('No return value is configured for %s::%s() and return value generation is disabled', $invocation->className(), $invocation->methodName()));
  56389. }
  56390. }
  56391. <?php
  56392. declare (strict_types=1);
  56393. /*
  56394. * This file is part of PHPUnit.
  56395. *
  56396. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56397. *
  56398. * For the full copyright and license information, please view the LICENSE
  56399. * file that was distributed with this source code.
  56400. */
  56401. namespace PHPUnit\Framework\MockObject;
  56402. /**
  56403. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56404. *
  56405. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56406. */
  56407. final class RuntimeException extends \RuntimeException implements \PHPUnit\Framework\MockObject\Exception
  56408. {
  56409. }
  56410. <?php
  56411. declare (strict_types=1);
  56412. /*
  56413. * This file is part of PHPUnit.
  56414. *
  56415. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56416. *
  56417. * For the full copyright and license information, please view the LICENSE
  56418. * file that was distributed with this source code.
  56419. */
  56420. namespace PHPUnit\Framework\MockObject\Generator;
  56421. use function sprintf;
  56422. /**
  56423. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56424. *
  56425. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56426. */
  56427. final class CannotUseAddMethodsException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56428. {
  56429. public function __construct(string $type, string $methodName)
  56430. {
  56431. parent::__construct(sprintf('Trying to configure method "%s" with addMethods(), but it exists in class "%s". Use onlyMethods() for methods that exist in the class', $methodName, $type));
  56432. }
  56433. }
  56434. <?php
  56435. declare (strict_types=1);
  56436. /*
  56437. * This file is part of PHPUnit.
  56438. *
  56439. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56440. *
  56441. * For the full copyright and license information, please view the LICENSE
  56442. * file that was distributed with this source code.
  56443. */
  56444. namespace PHPUnit\Framework\MockObject\Generator;
  56445. use function sprintf;
  56446. /**
  56447. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56448. *
  56449. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56450. */
  56451. final class ClassIsEnumerationException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56452. {
  56453. public function __construct(string $className)
  56454. {
  56455. parent::__construct(sprintf('Class "%s" is an enumeration and cannot be doubled', $className));
  56456. }
  56457. }
  56458. <?php
  56459. declare (strict_types=1);
  56460. /*
  56461. * This file is part of PHPUnit.
  56462. *
  56463. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56464. *
  56465. * For the full copyright and license information, please view the LICENSE
  56466. * file that was distributed with this source code.
  56467. */
  56468. namespace PHPUnit\Framework\MockObject\Generator;
  56469. use function sprintf;
  56470. /**
  56471. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56472. *
  56473. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56474. */
  56475. final class ClassIsFinalException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56476. {
  56477. public function __construct(string $className)
  56478. {
  56479. parent::__construct(sprintf('Class "%s" is declared "final" and cannot be doubled', $className));
  56480. }
  56481. }
  56482. <?php
  56483. declare (strict_types=1);
  56484. /*
  56485. * This file is part of PHPUnit.
  56486. *
  56487. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56488. *
  56489. * For the full copyright and license information, please view the LICENSE
  56490. * file that was distributed with this source code.
  56491. */
  56492. namespace PHPUnit\Framework\MockObject\Generator;
  56493. use function sprintf;
  56494. /**
  56495. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56496. *
  56497. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56498. */
  56499. final class ClassIsReadonlyException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56500. {
  56501. public function __construct(string $className)
  56502. {
  56503. parent::__construct(sprintf('Class "%s" is declared "readonly" and cannot be doubled', $className));
  56504. }
  56505. }
  56506. <?php
  56507. declare (strict_types=1);
  56508. /*
  56509. * This file is part of PHPUnit.
  56510. *
  56511. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56512. *
  56513. * For the full copyright and license information, please view the LICENSE
  56514. * file that was distributed with this source code.
  56515. */
  56516. namespace PHPUnit\Framework\MockObject\Generator;
  56517. use function array_diff_assoc;
  56518. use function array_unique;
  56519. use function implode;
  56520. use function sprintf;
  56521. /**
  56522. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56523. *
  56524. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56525. */
  56526. final class DuplicateMethodException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56527. {
  56528. /**
  56529. * @psalm-param list<string> $methods
  56530. */
  56531. public function __construct(array $methods)
  56532. {
  56533. parent::__construct(sprintf('Cannot double using a method list that contains duplicates: "%s" (duplicate: "%s")', implode(', ', $methods), implode(', ', array_unique(array_diff_assoc($methods, array_unique($methods))))));
  56534. }
  56535. }
  56536. <?php
  56537. declare (strict_types=1);
  56538. /*
  56539. * This file is part of PHPUnit.
  56540. *
  56541. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56542. *
  56543. * For the full copyright and license information, please view the LICENSE
  56544. * file that was distributed with this source code.
  56545. */
  56546. namespace PHPUnit\Framework\MockObject\Generator;
  56547. use PHPUnit\Framework\MockObject\Exception as BaseException;
  56548. /**
  56549. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56550. *
  56551. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  56552. */
  56553. interface Exception extends BaseException
  56554. {
  56555. }
  56556. <?php
  56557. declare (strict_types=1);
  56558. /*
  56559. * This file is part of PHPUnit.
  56560. *
  56561. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56562. *
  56563. * For the full copyright and license information, please view the LICENSE
  56564. * file that was distributed with this source code.
  56565. */
  56566. namespace PHPUnit\Framework\MockObject\Generator;
  56567. use function sprintf;
  56568. /**
  56569. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56570. *
  56571. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56572. */
  56573. final class InvalidMethodNameException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56574. {
  56575. public function __construct(string $method)
  56576. {
  56577. parent::__construct(sprintf('Cannot double method with invalid name "%s"', $method));
  56578. }
  56579. }
  56580. <?php
  56581. declare (strict_types=1);
  56582. /*
  56583. * This file is part of PHPUnit.
  56584. *
  56585. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56586. *
  56587. * For the full copyright and license information, please view the LICENSE
  56588. * file that was distributed with this source code.
  56589. */
  56590. namespace PHPUnit\Framework\MockObject\Generator;
  56591. use function sprintf;
  56592. /**
  56593. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56594. *
  56595. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56596. */
  56597. final class NameAlreadyInUseException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56598. {
  56599. /**
  56600. * @psalm-param class-string|trait-string $name
  56601. */
  56602. public function __construct(string $name)
  56603. {
  56604. parent::__construct(sprintf('The name "%s" is already in use', $name));
  56605. }
  56606. }
  56607. <?php
  56608. declare (strict_types=1);
  56609. /*
  56610. * This file is part of PHPUnit.
  56611. *
  56612. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56613. *
  56614. * For the full copyright and license information, please view the LICENSE
  56615. * file that was distributed with this source code.
  56616. */
  56617. namespace PHPUnit\Framework\MockObject\Generator;
  56618. /**
  56619. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56620. *
  56621. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56622. */
  56623. final class OriginalConstructorInvocationRequiredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56624. {
  56625. public function __construct()
  56626. {
  56627. parent::__construct('Proxying to original methods requires invoking the original constructor');
  56628. }
  56629. }
  56630. <?php
  56631. declare (strict_types=1);
  56632. /*
  56633. * This file is part of PHPUnit.
  56634. *
  56635. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56636. *
  56637. * For the full copyright and license information, please view the LICENSE
  56638. * file that was distributed with this source code.
  56639. */
  56640. namespace PHPUnit\Framework\MockObject\Generator;
  56641. /**
  56642. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56643. *
  56644. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56645. */
  56646. final class ReflectionException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56647. {
  56648. }
  56649. <?php
  56650. declare (strict_types=1);
  56651. /*
  56652. * This file is part of PHPUnit.
  56653. *
  56654. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56655. *
  56656. * For the full copyright and license information, please view the LICENSE
  56657. * file that was distributed with this source code.
  56658. */
  56659. namespace PHPUnit\Framework\MockObject\Generator;
  56660. /**
  56661. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56662. *
  56663. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56664. */
  56665. final class RuntimeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56666. {
  56667. }
  56668. <?php
  56669. declare (strict_types=1);
  56670. /*
  56671. * This file is part of PHPUnit.
  56672. *
  56673. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56674. *
  56675. * For the full copyright and license information, please view the LICENSE
  56676. * file that was distributed with this source code.
  56677. */
  56678. namespace PHPUnit\Framework\MockObject\Generator;
  56679. /**
  56680. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56681. *
  56682. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56683. */
  56684. final class SoapExtensionNotAvailableException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56685. {
  56686. public function __construct()
  56687. {
  56688. parent::__construct('The SOAP extension is required to generate a test double from WSDL');
  56689. }
  56690. }
  56691. <?php
  56692. declare (strict_types=1);
  56693. /*
  56694. * This file is part of PHPUnit.
  56695. *
  56696. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56697. *
  56698. * For the full copyright and license information, please view the LICENSE
  56699. * file that was distributed with this source code.
  56700. */
  56701. namespace PHPUnit\Framework\MockObject\Generator;
  56702. use function sprintf;
  56703. /**
  56704. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56705. *
  56706. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56707. */
  56708. final class UnknownClassException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56709. {
  56710. public function __construct(string $className)
  56711. {
  56712. parent::__construct(sprintf('Class "%s" does not exist', $className));
  56713. }
  56714. }
  56715. <?php
  56716. declare (strict_types=1);
  56717. /*
  56718. * This file is part of PHPUnit.
  56719. *
  56720. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56721. *
  56722. * For the full copyright and license information, please view the LICENSE
  56723. * file that was distributed with this source code.
  56724. */
  56725. namespace PHPUnit\Framework\MockObject\Generator;
  56726. use function sprintf;
  56727. /**
  56728. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56729. *
  56730. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56731. *
  56732. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
  56733. */
  56734. final class UnknownTraitException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56735. {
  56736. public function __construct(string $traitName)
  56737. {
  56738. parent::__construct(sprintf('Trait "%s" does not exist', $traitName));
  56739. }
  56740. }
  56741. <?php
  56742. declare (strict_types=1);
  56743. /*
  56744. * This file is part of PHPUnit.
  56745. *
  56746. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56747. *
  56748. * For the full copyright and license information, please view the LICENSE
  56749. * file that was distributed with this source code.
  56750. */
  56751. namespace PHPUnit\Framework\MockObject\Generator;
  56752. use function sprintf;
  56753. /**
  56754. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56755. *
  56756. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56757. */
  56758. final class UnknownTypeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
  56759. {
  56760. public function __construct(string $type)
  56761. {
  56762. parent::__construct(sprintf('Class or interface "%s" does not exist', $type));
  56763. }
  56764. }
  56765. <?php
  56766. declare (strict_types=1);
  56767. /*
  56768. * This file is part of PHPUnit.
  56769. *
  56770. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56771. *
  56772. * For the full copyright and license information, please view the LICENSE
  56773. * file that was distributed with this source code.
  56774. */
  56775. namespace PHPUnit\Framework\MockObject\Generator;
  56776. use const PHP_EOL;
  56777. use const PREG_OFFSET_CAPTURE;
  56778. use const WSDL_CACHE_NONE;
  56779. use function array_merge;
  56780. use function array_pop;
  56781. use function array_unique;
  56782. use function assert;
  56783. use function class_exists;
  56784. use function count;
  56785. use function explode;
  56786. use function extension_loaded;
  56787. use function implode;
  56788. use function in_array;
  56789. use function interface_exists;
  56790. use function is_array;
  56791. use function is_object;
  56792. use function md5;
  56793. use function method_exists;
  56794. use function mt_rand;
  56795. use function preg_match;
  56796. use function preg_match_all;
  56797. use function range;
  56798. use function serialize;
  56799. use function sort;
  56800. use function sprintf;
  56801. use function str_contains;
  56802. use function str_replace;
  56803. use function strlen;
  56804. use function strpos;
  56805. use function substr;
  56806. use function trait_exists;
  56807. use Exception;
  56808. use Iterator;
  56809. use IteratorAggregate;
  56810. use PHPUnit\Framework\InvalidArgumentException;
  56811. use PHPUnit\Framework\MockObject\ConfigurableMethod;
  56812. use PHPUnit\Framework\MockObject\DoubledCloneMethod;
  56813. use PHPUnit\Framework\MockObject\Method;
  56814. use PHPUnit\Framework\MockObject\MockObject;
  56815. use PHPUnit\Framework\MockObject\MockObjectApi;
  56816. use PHPUnit\Framework\MockObject\MockObjectInternal;
  56817. use PHPUnit\Framework\MockObject\ProxiedCloneMethod;
  56818. use PHPUnit\Framework\MockObject\Stub;
  56819. use PHPUnit\Framework\MockObject\StubApi;
  56820. use PHPUnit\Framework\MockObject\StubInternal;
  56821. use ReflectionClass;
  56822. use ReflectionMethod;
  56823. use SoapClient;
  56824. use SoapFault;
  56825. use Throwable;
  56826. use Traversable;
  56827. /**
  56828. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  56829. *
  56830. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  56831. */
  56832. final class Generator
  56833. {
  56834. use \PHPUnit\Framework\MockObject\Generator\TemplateLoader;
  56835. /**
  56836. * @var array
  56837. */
  56838. private const EXCLUDED_METHOD_NAMES = ['__CLASS__' => \true, '__DIR__' => \true, '__FILE__' => \true, '__FUNCTION__' => \true, '__LINE__' => \true, '__METHOD__' => \true, '__NAMESPACE__' => \true, '__TRAIT__' => \true, '__clone' => \true, '__halt_compiler' => \true];
  56839. /**
  56840. * @psalm-var array<non-empty-string, MockClass>
  56841. */
  56842. private static array $cache = [];
  56843. /**
  56844. * Returns a test double for the specified class.
  56845. *
  56846. * @throws ClassIsEnumerationException
  56847. * @throws ClassIsFinalException
  56848. * @throws ClassIsReadonlyException
  56849. * @throws DuplicateMethodException
  56850. * @throws InvalidMethodNameException
  56851. * @throws NameAlreadyInUseException
  56852. * @throws OriginalConstructorInvocationRequiredException
  56853. * @throws ReflectionException
  56854. * @throws RuntimeException
  56855. * @throws UnknownTypeException
  56856. */
  56857. public function testDouble(string $type, bool $mockObject, ?array $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false, ?object $proxyTarget = null, bool $allowMockingUnknownTypes = \true, bool $returnValueGeneration = \true): MockObject|Stub
  56858. {
  56859. if ($type === Traversable::class) {
  56860. $type = Iterator::class;
  56861. }
  56862. if (!$allowMockingUnknownTypes) {
  56863. $this->ensureKnownType($type, $callAutoload);
  56864. }
  56865. $this->ensureValidMethods($methods);
  56866. $this->ensureNameForTestDoubleClassIsAvailable($mockClassName);
  56867. if (!$callOriginalConstructor && $callOriginalMethods) {
  56868. throw new \PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException();
  56869. }
  56870. $mock = $this->generate($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
  56871. $object = $this->getObject($mock, $type, $callOriginalConstructor, $arguments, $callOriginalMethods, $proxyTarget, $returnValueGeneration);
  56872. assert($object instanceof $type);
  56873. if ($mockObject) {
  56874. assert($object instanceof MockObject);
  56875. } else {
  56876. assert($object instanceof Stub);
  56877. }
  56878. return $object;
  56879. }
  56880. /**
  56881. * @psalm-param list<class-string> $interfaces
  56882. *
  56883. * @throws RuntimeException
  56884. * @throws UnknownTypeException
  56885. */
  56886. public function testDoubleForInterfaceIntersection(array $interfaces, bool $mockObject, bool $callAutoload = \true): MockObject|Stub
  56887. {
  56888. if (count($interfaces) < 2) {
  56889. throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('At least two interfaces must be specified');
  56890. }
  56891. foreach ($interfaces as $interface) {
  56892. if (!interface_exists($interface, $callAutoload)) {
  56893. throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($interface);
  56894. }
  56895. }
  56896. sort($interfaces);
  56897. $methods = [];
  56898. foreach ($interfaces as $interface) {
  56899. $methods = array_merge($methods, $this->namesOfMethodsIn($interface));
  56900. }
  56901. if (count(array_unique($methods)) < count($methods)) {
  56902. throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('Interfaces must not declare the same method');
  56903. }
  56904. $unqualifiedNames = [];
  56905. foreach ($interfaces as $interface) {
  56906. $parts = explode('\\', $interface);
  56907. $unqualifiedNames[] = array_pop($parts);
  56908. }
  56909. sort($unqualifiedNames);
  56910. do {
  56911. $intersectionName = sprintf('Intersection_%s_%s', implode('_', $unqualifiedNames), substr(md5((string) mt_rand()), 0, 8));
  56912. } while (interface_exists($intersectionName, \false));
  56913. $template = $this->loadTemplate('intersection.tpl');
  56914. $template->setVar(['intersection' => $intersectionName, 'interfaces' => implode(', ', $interfaces)]);
  56915. eval($template->render());
  56916. return $this->testDouble($intersectionName, $mockObject);
  56917. }
  56918. /**
  56919. * Returns a mock object for the specified abstract class with all abstract
  56920. * methods of the class mocked.
  56921. *
  56922. * Concrete methods to mock can be specified with the $mockedMethods parameter.
  56923. *
  56924. * @throws ClassIsEnumerationException
  56925. * @throws ClassIsFinalException
  56926. * @throws ClassIsReadonlyException
  56927. * @throws DuplicateMethodException
  56928. * @throws InvalidArgumentException
  56929. * @throws InvalidMethodNameException
  56930. * @throws NameAlreadyInUseException
  56931. * @throws OriginalConstructorInvocationRequiredException
  56932. * @throws ReflectionException
  56933. * @throws RuntimeException
  56934. * @throws UnknownClassException
  56935. * @throws UnknownTypeException
  56936. *
  56937. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241
  56938. */
  56939. public function mockObjectForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, ?array $mockedMethods = null, bool $cloneArguments = \true): MockObject
  56940. {
  56941. if (class_exists($originalClassName, $callAutoload) || interface_exists($originalClassName, $callAutoload)) {
  56942. $reflector = $this->reflectClass($originalClassName);
  56943. $methods = $mockedMethods;
  56944. foreach ($reflector->getMethods() as $method) {
  56945. if ($method->isAbstract() && !in_array($method->getName(), $methods ?? [], \true)) {
  56946. $methods[] = $method->getName();
  56947. }
  56948. }
  56949. if (empty($methods)) {
  56950. $methods = null;
  56951. }
  56952. $mockObject = $this->testDouble($originalClassName, \true, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments);
  56953. assert($mockObject instanceof $originalClassName);
  56954. assert($mockObject instanceof MockObject);
  56955. return $mockObject;
  56956. }
  56957. throw new \PHPUnit\Framework\MockObject\Generator\UnknownClassException($originalClassName);
  56958. }
  56959. /**
  56960. * Returns a mock object for the specified trait with all abstract methods
  56961. * of the trait mocked. Concrete methods to mock can be specified with the
  56962. * `$mockedMethods` parameter.
  56963. *
  56964. * @psalm-param trait-string $traitName
  56965. *
  56966. * @throws ClassIsEnumerationException
  56967. * @throws ClassIsFinalException
  56968. * @throws ClassIsReadonlyException
  56969. * @throws DuplicateMethodException
  56970. * @throws InvalidArgumentException
  56971. * @throws InvalidMethodNameException
  56972. * @throws NameAlreadyInUseException
  56973. * @throws OriginalConstructorInvocationRequiredException
  56974. * @throws ReflectionException
  56975. * @throws RuntimeException
  56976. * @throws UnknownClassException
  56977. * @throws UnknownTraitException
  56978. * @throws UnknownTypeException
  56979. *
  56980. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
  56981. */
  56982. public function mockObjectForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, ?array $mockedMethods = null, bool $cloneArguments = \true): MockObject
  56983. {
  56984. if (!trait_exists($traitName, $callAutoload)) {
  56985. throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName);
  56986. }
  56987. $className = $this->generateClassName($traitName, '', 'Trait_');
  56988. $classTemplate = $this->loadTemplate('trait_class.tpl');
  56989. $classTemplate->setVar(['prologue' => 'abstract ', 'class_name' => $className['className'], 'trait_name' => $traitName]);
  56990. $mockTrait = new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']);
  56991. $mockTrait->generate();
  56992. return $this->mockObjectForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
  56993. }
  56994. /**
  56995. * Returns an object for the specified trait.
  56996. *
  56997. * @psalm-param trait-string $traitName
  56998. *
  56999. * @throws ReflectionException
  57000. * @throws RuntimeException
  57001. * @throws UnknownTraitException
  57002. *
  57003. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244
  57004. */
  57005. public function objectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = \true, bool $callOriginalConstructor = \false, array $arguments = []): object
  57006. {
  57007. if (!trait_exists($traitName, $callAutoload)) {
  57008. throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName);
  57009. }
  57010. $className = $this->generateClassName($traitName, $traitClassName, 'Trait_');
  57011. $classTemplate = $this->loadTemplate('trait_class.tpl');
  57012. $classTemplate->setVar(['prologue' => '', 'class_name' => $className['className'], 'trait_name' => $traitName]);
  57013. return $this->getObject(new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']), '', $callOriginalConstructor, $arguments);
  57014. }
  57015. /**
  57016. * @throws ClassIsEnumerationException
  57017. * @throws ClassIsFinalException
  57018. * @throws ClassIsReadonlyException
  57019. * @throws ReflectionException
  57020. * @throws RuntimeException
  57021. *
  57022. * @todo This method is only public because it is used to test generated code in PHPT tests
  57023. *
  57024. * @see https://github.com/sebastianbergmann/phpunit/issues/5476
  57025. */
  57026. public function generate(string $type, bool $mockObject, ?array $methods = null, string $mockClassName = '', bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false): \PHPUnit\Framework\MockObject\Generator\MockClass
  57027. {
  57028. if ($mockClassName !== '') {
  57029. return $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
  57030. }
  57031. $key = md5($type . ($mockObject ? 'MockObject' : 'TestStub') . serialize($methods) . serialize($callOriginalClone) . serialize($cloneArguments) . serialize($callOriginalMethods));
  57032. if (!isset(self::$cache[$key])) {
  57033. self::$cache[$key] = $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
  57034. }
  57035. return self::$cache[$key];
  57036. }
  57037. /**
  57038. * @throws RuntimeException
  57039. * @throws SoapExtensionNotAvailableException
  57040. *
  57041. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242
  57042. */
  57043. public function generateClassFromWsdl(string $wsdlFile, string $className, array $methods = [], array $options = []): string
  57044. {
  57045. if (!extension_loaded('soap')) {
  57046. throw new \PHPUnit\Framework\MockObject\Generator\SoapExtensionNotAvailableException();
  57047. }
  57048. $options['cache_wsdl'] = WSDL_CACHE_NONE;
  57049. try {
  57050. $client = new SoapClient($wsdlFile, $options);
  57051. $_methods = array_unique($client->__getFunctions());
  57052. unset($client);
  57053. } catch (SoapFault $e) {
  57054. throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException($e->getMessage(), $e->getCode(), $e);
  57055. }
  57056. sort($_methods);
  57057. $methodTemplate = $this->loadTemplate('wsdl_method.tpl');
  57058. $methodsBuffer = '';
  57059. foreach ($_methods as $method) {
  57060. preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(/', $method, $matches, PREG_OFFSET_CAPTURE);
  57061. $lastFunction = array_pop($matches[0]);
  57062. $nameStart = $lastFunction[1];
  57063. $nameEnd = $nameStart + strlen($lastFunction[0]) - 1;
  57064. $name = str_replace('(', '', $lastFunction[0]);
  57065. if (empty($methods) || in_array($name, $methods, \true)) {
  57066. $arguments = explode(',', str_replace(')', '', substr($method, $nameEnd + 1)));
  57067. foreach (range(0, count($arguments) - 1) as $i) {
  57068. $parameterStart = strpos($arguments[$i], '$');
  57069. if (!$parameterStart) {
  57070. continue;
  57071. }
  57072. $arguments[$i] = substr($arguments[$i], $parameterStart);
  57073. }
  57074. $methodTemplate->setVar(['method_name' => $name, 'arguments' => implode(', ', $arguments)]);
  57075. $methodsBuffer .= $methodTemplate->render();
  57076. }
  57077. }
  57078. $optionsBuffer = '[';
  57079. foreach ($options as $key => $value) {
  57080. $optionsBuffer .= $key . ' => ' . $value;
  57081. }
  57082. $optionsBuffer .= ']';
  57083. $classTemplate = $this->loadTemplate('wsdl_class.tpl');
  57084. $namespace = '';
  57085. if (str_contains($className, '\\')) {
  57086. $parts = explode('\\', $className);
  57087. $className = array_pop($parts);
  57088. $namespace = 'namespace ' . implode('\\', $parts) . ';' . "\n\n";
  57089. }
  57090. $classTemplate->setVar(['namespace' => $namespace, 'class_name' => $className, 'wsdl' => $wsdlFile, 'options' => $optionsBuffer, 'methods' => $methodsBuffer]);
  57091. return $classTemplate->render();
  57092. }
  57093. /**
  57094. * @throws ReflectionException
  57095. *
  57096. * @psalm-return list<MockMethod>
  57097. */
  57098. public function mockClassMethods(string $className, bool $callOriginalMethods, bool $cloneArguments): array
  57099. {
  57100. $class = $this->reflectClass($className);
  57101. $methods = [];
  57102. foreach ($class->getMethods() as $method) {
  57103. if (($method->isPublic() || $method->isAbstract()) && $this->canMethodBeDoubled($method)) {
  57104. $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments);
  57105. }
  57106. }
  57107. return $methods;
  57108. }
  57109. /**
  57110. * @psalm-param class-string $interfaceName
  57111. *
  57112. * @throws ReflectionException
  57113. *
  57114. * @psalm-return list<ReflectionMethod>
  57115. */
  57116. private function userDefinedInterfaceMethods(string $interfaceName): array
  57117. {
  57118. $interface = $this->reflectClass($interfaceName);
  57119. $methods = [];
  57120. foreach ($interface->getMethods() as $method) {
  57121. if (!$method->isUserDefined()) {
  57122. continue;
  57123. }
  57124. $methods[] = $method;
  57125. }
  57126. return $methods;
  57127. }
  57128. /**
  57129. * @throws ReflectionException
  57130. * @throws RuntimeException
  57131. */
  57132. private function getObject(\PHPUnit\Framework\MockObject\Generator\MockType $mockClass, string $type = '', bool $callOriginalConstructor = \false, array $arguments = [], bool $callOriginalMethods = \false, ?object $proxyTarget = null, bool $returnValueGeneration = \true): object
  57133. {
  57134. $className = $mockClass->generate();
  57135. $object = $this->instantiate($className, $callOriginalConstructor, $arguments);
  57136. if ($callOriginalMethods) {
  57137. $this->instantiateProxyTarget($proxyTarget, $object, $type, $arguments);
  57138. }
  57139. if ($object instanceof StubInternal) {
  57140. $object->__phpunit_setReturnValueGeneration($returnValueGeneration);
  57141. }
  57142. return $object;
  57143. }
  57144. /**
  57145. * @throws ClassIsEnumerationException
  57146. * @throws ClassIsFinalException
  57147. * @throws ClassIsReadonlyException
  57148. * @throws ReflectionException
  57149. * @throws RuntimeException
  57150. */
  57151. private function generateCodeForTestDoubleClass(string $type, bool $mockObject, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): \PHPUnit\Framework\MockObject\Generator\MockClass
  57152. {
  57153. $classTemplate = $this->loadTemplate('test_double_class.tpl');
  57154. $additionalInterfaces = [];
  57155. $doubledCloneMethod = \false;
  57156. $proxiedCloneMethod = \false;
  57157. $isClass = \false;
  57158. $isInterface = \false;
  57159. $class = null;
  57160. $mockMethods = new \PHPUnit\Framework\MockObject\Generator\MockMethodSet();
  57161. $testDoubleClassPrefix = $mockObject ? 'MockObject_' : 'TestStub_';
  57162. $_mockClassName = $this->generateClassName($type, $mockClassName, $testDoubleClassPrefix);
  57163. if (class_exists($_mockClassName['fullClassName'], $callAutoload)) {
  57164. $isClass = \true;
  57165. } elseif (interface_exists($_mockClassName['fullClassName'], $callAutoload)) {
  57166. $isInterface = \true;
  57167. }
  57168. if (!$isClass && !$isInterface) {
  57169. $prologue = 'class ' . $_mockClassName['originalClassName'] . "\n{\n}\n\n";
  57170. if (!empty($_mockClassName['namespaceName'])) {
  57171. $prologue = 'namespace ' . $_mockClassName['namespaceName'] . " {\n\n" . $prologue . "}\n\n" . "namespace {\n\n";
  57172. $epilogue = "\n\n}";
  57173. }
  57174. $doubledCloneMethod = \true;
  57175. } else {
  57176. $class = $this->reflectClass($_mockClassName['fullClassName']);
  57177. if ($class->isEnum()) {
  57178. throw new \PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException($_mockClassName['fullClassName']);
  57179. }
  57180. if ($class->isFinal()) {
  57181. throw new \PHPUnit\Framework\MockObject\Generator\ClassIsFinalException($_mockClassName['fullClassName']);
  57182. }
  57183. if (method_exists($class, 'isReadOnly') && $class->isReadOnly()) {
  57184. throw new \PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException($_mockClassName['fullClassName']);
  57185. }
  57186. // @see https://github.com/sebastianbergmann/phpunit/issues/2995
  57187. if ($isInterface && $class->implementsInterface(Throwable::class)) {
  57188. $actualClassName = Exception::class;
  57189. $additionalInterfaces[] = $class->getName();
  57190. $isInterface = \false;
  57191. $class = $this->reflectClass($actualClassName);
  57192. foreach ($this->userDefinedInterfaceMethods($_mockClassName['fullClassName']) as $method) {
  57193. $methodName = $method->getName();
  57194. if ($class->hasMethod($methodName)) {
  57195. $classMethod = $class->getMethod($methodName);
  57196. if (!$this->canMethodBeDoubled($classMethod)) {
  57197. continue;
  57198. }
  57199. }
  57200. $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments));
  57201. }
  57202. $_mockClassName = $this->generateClassName($actualClassName, $_mockClassName['className'], $testDoubleClassPrefix);
  57203. }
  57204. // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
  57205. if ($isInterface && $class->implementsInterface(Traversable::class) && !$class->implementsInterface(Iterator::class) && !$class->implementsInterface(IteratorAggregate::class)) {
  57206. $additionalInterfaces[] = Iterator::class;
  57207. $mockMethods->addMethods(...$this->mockClassMethods(Iterator::class, $callOriginalMethods, $cloneArguments));
  57208. }
  57209. if ($class->hasMethod('__clone')) {
  57210. $cloneMethod = $class->getMethod('__clone');
  57211. if (!$cloneMethod->isFinal()) {
  57212. if ($callOriginalClone && !$isInterface) {
  57213. $proxiedCloneMethod = \true;
  57214. } else {
  57215. $doubledCloneMethod = \true;
  57216. }
  57217. }
  57218. } else {
  57219. $doubledCloneMethod = \true;
  57220. }
  57221. }
  57222. if ($isClass && $explicitMethods === []) {
  57223. $mockMethods->addMethods(...$this->mockClassMethods($_mockClassName['fullClassName'], $callOriginalMethods, $cloneArguments));
  57224. }
  57225. if ($isInterface && ($explicitMethods === [] || $explicitMethods === null)) {
  57226. $mockMethods->addMethods(...$this->interfaceMethods($_mockClassName['fullClassName'], $cloneArguments));
  57227. }
  57228. if (is_array($explicitMethods)) {
  57229. foreach ($explicitMethods as $methodName) {
  57230. if ($class !== null && $class->hasMethod($methodName)) {
  57231. $method = $class->getMethod($methodName);
  57232. if ($this->canMethodBeDoubled($method)) {
  57233. $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments));
  57234. }
  57235. } else {
  57236. $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromName($_mockClassName['fullClassName'], $methodName, $cloneArguments));
  57237. }
  57238. }
  57239. }
  57240. $mockedMethods = '';
  57241. $configurable = [];
  57242. foreach ($mockMethods->asArray() as $mockMethod) {
  57243. $mockedMethods .= $mockMethod->generateCode();
  57244. $configurable[] = new ConfigurableMethod($mockMethod->methodName(), $mockMethod->defaultParameterValues(), $mockMethod->numberOfParameters(), $mockMethod->returnType());
  57245. }
  57246. /** @psalm-var trait-string[] $traits */
  57247. $traits = [StubApi::class];
  57248. if ($mockObject) {
  57249. $traits[] = MockObjectApi::class;
  57250. }
  57251. if (!$mockMethods->hasMethod('method') && (!isset($class) || !$class->hasMethod('method'))) {
  57252. $traits[] = Method::class;
  57253. }
  57254. if ($doubledCloneMethod) {
  57255. $traits[] = DoubledCloneMethod::class;
  57256. }
  57257. if ($proxiedCloneMethod) {
  57258. $traits[] = ProxiedCloneMethod::class;
  57259. }
  57260. $useStatements = '';
  57261. foreach ($traits as $trait) {
  57262. $useStatements .= sprintf(' use %s;' . PHP_EOL, $trait);
  57263. }
  57264. unset($traits);
  57265. $classTemplate->setVar(['prologue' => $prologue ?? '', 'epilogue' => $epilogue ?? '', 'class_declaration' => $this->generateTestDoubleClassDeclaration($mockObject, $_mockClassName, $isInterface, $additionalInterfaces), 'use_statements' => $useStatements, 'mock_class_name' => $_mockClassName['className'], 'mocked_methods' => $mockedMethods]);
  57266. return new \PHPUnit\Framework\MockObject\Generator\MockClass($classTemplate->render(), $_mockClassName['className'], $configurable);
  57267. }
  57268. private function generateClassName(string $type, string $className, string $prefix): array
  57269. {
  57270. if ($type[0] === '\\') {
  57271. $type = substr($type, 1);
  57272. }
  57273. $classNameParts = explode('\\', $type);
  57274. if (count($classNameParts) > 1) {
  57275. $type = array_pop($classNameParts);
  57276. $namespaceName = implode('\\', $classNameParts);
  57277. $fullClassName = $namespaceName . '\\' . $type;
  57278. } else {
  57279. $namespaceName = '';
  57280. $fullClassName = $type;
  57281. }
  57282. if ($className === '') {
  57283. do {
  57284. $className = $prefix . $type . '_' . substr(md5((string) mt_rand()), 0, 8);
  57285. } while (class_exists($className, \false));
  57286. }
  57287. return ['className' => $className, 'originalClassName' => $type, 'fullClassName' => $fullClassName, 'namespaceName' => $namespaceName];
  57288. }
  57289. private function generateTestDoubleClassDeclaration(bool $mockObject, array $mockClassName, bool $isInterface, array $additionalInterfaces = []): string
  57290. {
  57291. if ($mockObject) {
  57292. $additionalInterfaces[] = MockObjectInternal::class;
  57293. } else {
  57294. $additionalInterfaces[] = StubInternal::class;
  57295. }
  57296. $buffer = 'class ';
  57297. $interfaces = implode(', ', $additionalInterfaces);
  57298. if ($isInterface) {
  57299. $buffer .= sprintf('%s implements %s', $mockClassName['className'], $interfaces);
  57300. if (!in_array($mockClassName['originalClassName'], $additionalInterfaces, \true)) {
  57301. $buffer .= ', ';
  57302. if (!empty($mockClassName['namespaceName'])) {
  57303. $buffer .= $mockClassName['namespaceName'] . '\\';
  57304. }
  57305. $buffer .= $mockClassName['originalClassName'];
  57306. }
  57307. } else {
  57308. $buffer .= sprintf('%s extends %s%s implements %s', $mockClassName['className'], !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', $mockClassName['originalClassName'], $interfaces);
  57309. }
  57310. return $buffer;
  57311. }
  57312. private function canMethodBeDoubled(ReflectionMethod $method): bool
  57313. {
  57314. if ($method->isConstructor()) {
  57315. return \false;
  57316. }
  57317. if ($method->isDestructor()) {
  57318. return \false;
  57319. }
  57320. if ($method->isFinal()) {
  57321. return \false;
  57322. }
  57323. if ($method->isPrivate()) {
  57324. return \false;
  57325. }
  57326. return !$this->isMethodNameExcluded($method->getName());
  57327. }
  57328. private function isMethodNameExcluded(string $name): bool
  57329. {
  57330. return isset(self::EXCLUDED_METHOD_NAMES[$name]);
  57331. }
  57332. /**
  57333. * @throws UnknownTypeException
  57334. */
  57335. private function ensureKnownType(string $type, bool $callAutoload): void
  57336. {
  57337. if (!class_exists($type, $callAutoload) && !interface_exists($type, $callAutoload)) {
  57338. throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($type);
  57339. }
  57340. }
  57341. /**
  57342. * @throws DuplicateMethodException
  57343. * @throws InvalidMethodNameException
  57344. */
  57345. private function ensureValidMethods(?array $methods): void
  57346. {
  57347. if ($methods === null) {
  57348. return;
  57349. }
  57350. foreach ($methods as $method) {
  57351. if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', (string) $method)) {
  57352. throw new \PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException((string) $method);
  57353. }
  57354. }
  57355. if ($methods !== array_unique($methods)) {
  57356. throw new \PHPUnit\Framework\MockObject\Generator\DuplicateMethodException($methods);
  57357. }
  57358. }
  57359. /**
  57360. * @throws NameAlreadyInUseException
  57361. * @throws ReflectionException
  57362. */
  57363. private function ensureNameForTestDoubleClassIsAvailable(string $className): void
  57364. {
  57365. if ($className === '') {
  57366. return;
  57367. }
  57368. if (class_exists($className, \false) || interface_exists($className, \false) || trait_exists($className, \false)) {
  57369. throw new \PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException($className);
  57370. }
  57371. }
  57372. /**
  57373. * @psalm-param class-string $className
  57374. *
  57375. * @throws ReflectionException
  57376. */
  57377. private function instantiate(string $className, bool $callOriginalConstructor, array $arguments): object
  57378. {
  57379. if ($callOriginalConstructor) {
  57380. if (count($arguments) === 0) {
  57381. return new $className();
  57382. }
  57383. try {
  57384. return (new ReflectionClass($className))->newInstanceArgs($arguments);
  57385. // @codeCoverageIgnoreStart
  57386. } catch (\ReflectionException $e) {
  57387. throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
  57388. }
  57389. // @codeCoverageIgnoreEnd
  57390. }
  57391. try {
  57392. return (new ReflectionClass($className))->newInstanceWithoutConstructor();
  57393. // @codeCoverageIgnoreStart
  57394. } catch (\ReflectionException $e) {
  57395. throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
  57396. // @codeCoverageIgnoreEnd
  57397. }
  57398. }
  57399. /**
  57400. * @psalm-param class-string $type
  57401. *
  57402. * @throws ReflectionException
  57403. */
  57404. private function instantiateProxyTarget(?object $proxyTarget, object $object, string $type, array $arguments): void
  57405. {
  57406. if (!is_object($proxyTarget)) {
  57407. assert(class_exists($type));
  57408. if (count($arguments) === 0) {
  57409. $proxyTarget = new $type();
  57410. } else {
  57411. $class = new ReflectionClass($type);
  57412. try {
  57413. $proxyTarget = $class->newInstanceArgs($arguments);
  57414. // @codeCoverageIgnoreStart
  57415. } catch (\ReflectionException $e) {
  57416. throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
  57417. }
  57418. // @codeCoverageIgnoreEnd
  57419. }
  57420. }
  57421. $object->__phpunit_setOriginalObject($proxyTarget);
  57422. }
  57423. /**
  57424. * @psalm-param class-string $className
  57425. *
  57426. * @throws ReflectionException
  57427. */
  57428. private function reflectClass(string $className): ReflectionClass
  57429. {
  57430. try {
  57431. $class = new ReflectionClass($className);
  57432. // @codeCoverageIgnoreStart
  57433. } catch (\ReflectionException $e) {
  57434. throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
  57435. }
  57436. // @codeCoverageIgnoreEnd
  57437. return $class;
  57438. }
  57439. /**
  57440. * @psalm-param class-string $classOrInterfaceName
  57441. *
  57442. * @psalm-return list<string>
  57443. *
  57444. * @throws ReflectionException
  57445. */
  57446. private function namesOfMethodsIn(string $classOrInterfaceName): array
  57447. {
  57448. $class = $this->reflectClass($classOrInterfaceName);
  57449. $methods = [];
  57450. foreach ($class->getMethods() as $method) {
  57451. if ($method->isPublic() || $method->isAbstract()) {
  57452. $methods[] = $method->getName();
  57453. }
  57454. }
  57455. return $methods;
  57456. }
  57457. /**
  57458. * @psalm-param class-string $interfaceName
  57459. *
  57460. * @psalm-return list<MockMethod>
  57461. *
  57462. * @throws ReflectionException
  57463. */
  57464. private function interfaceMethods(string $interfaceName, bool $cloneArguments): array
  57465. {
  57466. $class = $this->reflectClass($interfaceName);
  57467. $methods = [];
  57468. foreach ($class->getMethods() as $method) {
  57469. $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, \false, $cloneArguments);
  57470. }
  57471. return $methods;
  57472. }
  57473. }
  57474. <?php
  57475. declare (strict_types=1);
  57476. /*
  57477. * This file is part of PHPUnit.
  57478. *
  57479. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57480. *
  57481. * For the full copyright and license information, please view the LICENSE
  57482. * file that was distributed with this source code.
  57483. */
  57484. namespace PHPUnit\Framework\MockObject\Generator;
  57485. use function call_user_func;
  57486. use function class_exists;
  57487. use PHPUnit\Framework\MockObject\ConfigurableMethod;
  57488. /**
  57489. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57490. *
  57491. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  57492. */
  57493. final class MockClass implements \PHPUnit\Framework\MockObject\Generator\MockType
  57494. {
  57495. private readonly string $classCode;
  57496. /**
  57497. * @psalm-var class-string
  57498. */
  57499. private readonly string $mockName;
  57500. /**
  57501. * @psalm-var list<ConfigurableMethod>
  57502. */
  57503. private readonly array $configurableMethods;
  57504. /**
  57505. * @psalm-param class-string $mockName
  57506. * @psalm-param list<ConfigurableMethod> $configurableMethods
  57507. */
  57508. public function __construct(string $classCode, string $mockName, array $configurableMethods)
  57509. {
  57510. $this->classCode = $classCode;
  57511. $this->mockName = $mockName;
  57512. $this->configurableMethods = $configurableMethods;
  57513. }
  57514. /**
  57515. * @psalm-return class-string
  57516. */
  57517. public function generate(): string
  57518. {
  57519. if (!class_exists($this->mockName, \false)) {
  57520. eval($this->classCode);
  57521. call_user_func([$this->mockName, '__phpunit_initConfigurableMethods'], ...$this->configurableMethods);
  57522. }
  57523. return $this->mockName;
  57524. }
  57525. public function classCode(): string
  57526. {
  57527. return $this->classCode;
  57528. }
  57529. }
  57530. <?php
  57531. declare (strict_types=1);
  57532. /*
  57533. * This file is part of PHPUnit.
  57534. *
  57535. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57536. *
  57537. * For the full copyright and license information, please view the LICENSE
  57538. * file that was distributed with this source code.
  57539. */
  57540. namespace PHPUnit\Framework\MockObject\Generator;
  57541. use function count;
  57542. use function explode;
  57543. use function implode;
  57544. use function is_object;
  57545. use function is_string;
  57546. use function preg_match;
  57547. use function preg_replace;
  57548. use function sprintf;
  57549. use function str_contains;
  57550. use function strlen;
  57551. use function strpos;
  57552. use function substr;
  57553. use function substr_count;
  57554. use function trim;
  57555. use function var_export;
  57556. use ReflectionMethod;
  57557. use ReflectionParameter;
  57558. use PHPUnitPHAR\SebastianBergmann\Type\ReflectionMapper;
  57559. use PHPUnitPHAR\SebastianBergmann\Type\Type;
  57560. use PHPUnitPHAR\SebastianBergmann\Type\UnknownType;
  57561. /**
  57562. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57563. *
  57564. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  57565. */
  57566. final class MockMethod
  57567. {
  57568. use \PHPUnit\Framework\MockObject\Generator\TemplateLoader;
  57569. /**
  57570. * @psalm-var class-string
  57571. */
  57572. private readonly string $className;
  57573. /**
  57574. * @psalm-var non-empty-string
  57575. */
  57576. private readonly string $methodName;
  57577. private readonly bool $cloneArguments;
  57578. private readonly string $modifier;
  57579. private readonly string $argumentsForDeclaration;
  57580. private readonly string $argumentsForCall;
  57581. private readonly Type $returnType;
  57582. private readonly string $reference;
  57583. private readonly bool $callOriginalMethod;
  57584. private readonly bool $static;
  57585. private readonly ?string $deprecation;
  57586. /**
  57587. * @psalm-var array<int, mixed>
  57588. */
  57589. private readonly array $defaultParameterValues;
  57590. /**
  57591. * @psalm-var non-negative-int
  57592. */
  57593. private readonly int $numberOfParameters;
  57594. /**
  57595. * @throws ReflectionException
  57596. * @throws RuntimeException
  57597. */
  57598. public static function fromReflection(ReflectionMethod $method, bool $callOriginalMethod, bool $cloneArguments): self
  57599. {
  57600. if ($method->isPrivate()) {
  57601. $modifier = 'private';
  57602. } elseif ($method->isProtected()) {
  57603. $modifier = 'protected';
  57604. } else {
  57605. $modifier = 'public';
  57606. }
  57607. if ($method->isStatic()) {
  57608. $modifier .= ' static';
  57609. }
  57610. if ($method->returnsReference()) {
  57611. $reference = '&';
  57612. } else {
  57613. $reference = '';
  57614. }
  57615. $docComment = $method->getDocComment();
  57616. if (is_string($docComment) && preg_match('#\*[ \t]*+@deprecated[ \t]*+(.*?)\r?+\n[ \t]*+\*(?:[ \t]*+@|/$)#s', $docComment, $deprecation)) {
  57617. $deprecation = trim(preg_replace('#[ \t]*\r?\n[ \t]*+\*[ \t]*+#', ' ', $deprecation[1]));
  57618. } else {
  57619. $deprecation = null;
  57620. }
  57621. return new self($method->getDeclaringClass()->getName(), $method->getName(), $cloneArguments, $modifier, self::methodParametersForDeclaration($method), self::methodParametersForCall($method), self::methodParametersDefaultValues($method), count($method->getParameters()), (new ReflectionMapper())->fromReturnType($method), $reference, $callOriginalMethod, $method->isStatic(), $deprecation);
  57622. }
  57623. /**
  57624. * @param class-string $className
  57625. * @param non-empty-string $methodName
  57626. */
  57627. public static function fromName(string $className, string $methodName, bool $cloneArguments): self
  57628. {
  57629. return new self($className, $methodName, $cloneArguments, 'public', '', '', [], 0, new UnknownType(), '', \false, \false, null);
  57630. }
  57631. /**
  57632. * @psalm-param class-string $className
  57633. * @psalm-param non-empty-string $methodName
  57634. * @psalm-param array<int, mixed> $defaultParameterValues
  57635. * @psalm-param non-negative-int $numberOfParameters
  57636. */
  57637. private function __construct(string $className, string $methodName, bool $cloneArguments, string $modifier, string $argumentsForDeclaration, string $argumentsForCall, array $defaultParameterValues, int $numberOfParameters, Type $returnType, string $reference, bool $callOriginalMethod, bool $static, ?string $deprecation)
  57638. {
  57639. $this->className = $className;
  57640. $this->methodName = $methodName;
  57641. $this->cloneArguments = $cloneArguments;
  57642. $this->modifier = $modifier;
  57643. $this->argumentsForDeclaration = $argumentsForDeclaration;
  57644. $this->argumentsForCall = $argumentsForCall;
  57645. $this->defaultParameterValues = $defaultParameterValues;
  57646. $this->numberOfParameters = $numberOfParameters;
  57647. $this->returnType = $returnType;
  57648. $this->reference = $reference;
  57649. $this->callOriginalMethod = $callOriginalMethod;
  57650. $this->static = $static;
  57651. $this->deprecation = $deprecation;
  57652. }
  57653. /**
  57654. * @psalm-return non-empty-string
  57655. */
  57656. public function methodName(): string
  57657. {
  57658. return $this->methodName;
  57659. }
  57660. /**
  57661. * @throws RuntimeException
  57662. */
  57663. public function generateCode(): string
  57664. {
  57665. if ($this->static) {
  57666. $templateFile = 'doubled_static_method.tpl';
  57667. } else {
  57668. $templateFile = sprintf('%s_method.tpl', $this->callOriginalMethod ? 'proxied' : 'doubled');
  57669. }
  57670. $deprecation = $this->deprecation;
  57671. $returnResult = '';
  57672. if (!$this->returnType->isNever() && !$this->returnType->isVoid()) {
  57673. $returnResult = <<<'EOT'
  57674. return $__phpunit_result;
  57675. EOT;
  57676. }
  57677. if (null !== $this->deprecation) {
  57678. $deprecation = "The {$this->className}::{$this->methodName} method is deprecated ({$this->deprecation}).";
  57679. $deprecationTemplate = $this->loadTemplate('deprecation.tpl');
  57680. $deprecationTemplate->setVar(['deprecation' => var_export($deprecation, \true)]);
  57681. $deprecation = $deprecationTemplate->render();
  57682. }
  57683. $template = $this->loadTemplate($templateFile);
  57684. $argumentsCount = 0;
  57685. if (str_contains($this->argumentsForCall, '...')) {
  57686. $argumentsCount = null;
  57687. } elseif (!empty($this->argumentsForCall)) {
  57688. $argumentsCount = substr_count($this->argumentsForCall, ',') + 1;
  57689. }
  57690. $template->setVar(['arguments_decl' => $this->argumentsForDeclaration, 'arguments_call' => $this->argumentsForCall, 'return_declaration' => !empty($this->returnType->asString()) ? ': ' . $this->returnType->asString() : '', 'return_type' => $this->returnType->asString(), 'arguments_count' => $argumentsCount, 'class_name' => $this->className, 'method_name' => $this->methodName, 'modifier' => $this->modifier, 'reference' => $this->reference, 'clone_arguments' => $this->cloneArguments ? 'true' : 'false', 'deprecation' => $deprecation, 'return_result' => $returnResult]);
  57691. return $template->render();
  57692. }
  57693. public function returnType(): Type
  57694. {
  57695. return $this->returnType;
  57696. }
  57697. /**
  57698. * @psalm-return array<int, mixed>
  57699. */
  57700. public function defaultParameterValues(): array
  57701. {
  57702. return $this->defaultParameterValues;
  57703. }
  57704. /**
  57705. * @psalm-return non-negative-int
  57706. */
  57707. public function numberOfParameters(): int
  57708. {
  57709. return $this->numberOfParameters;
  57710. }
  57711. /**
  57712. * Returns the parameters of a function or method.
  57713. *
  57714. * @throws RuntimeException
  57715. */
  57716. private static function methodParametersForDeclaration(ReflectionMethod $method): string
  57717. {
  57718. $parameters = [];
  57719. $types = (new ReflectionMapper())->fromParameterTypes($method);
  57720. foreach ($method->getParameters() as $i => $parameter) {
  57721. $name = '$' . $parameter->getName();
  57722. /* Note: PHP extensions may use empty names for reference arguments
  57723. * or "..." for methods taking a variable number of arguments.
  57724. */
  57725. if ($name === '$' || $name === '$...') {
  57726. $name = '$arg' . $i;
  57727. }
  57728. $default = '';
  57729. $reference = '';
  57730. $typeDeclaration = '';
  57731. if (!$types[$i]->type()->isUnknown()) {
  57732. $typeDeclaration = $types[$i]->type()->asString() . ' ';
  57733. }
  57734. if ($parameter->isPassedByReference()) {
  57735. $reference = '&';
  57736. }
  57737. if ($parameter->isVariadic()) {
  57738. $name = '...' . $name;
  57739. } elseif ($parameter->isDefaultValueAvailable()) {
  57740. $default = ' = ' . self::exportDefaultValue($parameter);
  57741. } elseif ($parameter->isOptional()) {
  57742. $default = ' = null';
  57743. }
  57744. $parameters[] = $typeDeclaration . $reference . $name . $default;
  57745. }
  57746. return implode(', ', $parameters);
  57747. }
  57748. /**
  57749. * Returns the parameters of a function or method.
  57750. *
  57751. * @throws ReflectionException
  57752. */
  57753. private static function methodParametersForCall(ReflectionMethod $method): string
  57754. {
  57755. $parameters = [];
  57756. foreach ($method->getParameters() as $i => $parameter) {
  57757. $name = '$' . $parameter->getName();
  57758. /* Note: PHP extensions may use empty names for reference arguments
  57759. * or "..." for methods taking a variable number of arguments.
  57760. */
  57761. if ($name === '$' || $name === '$...') {
  57762. $name = '$arg' . $i;
  57763. }
  57764. if ($parameter->isVariadic()) {
  57765. continue;
  57766. }
  57767. if ($parameter->isPassedByReference()) {
  57768. $parameters[] = '&' . $name;
  57769. } else {
  57770. $parameters[] = $name;
  57771. }
  57772. }
  57773. return implode(', ', $parameters);
  57774. }
  57775. /**
  57776. * @throws ReflectionException
  57777. */
  57778. private static function exportDefaultValue(ReflectionParameter $parameter): string
  57779. {
  57780. try {
  57781. $defaultValue = $parameter->getDefaultValue();
  57782. if (!is_object($defaultValue)) {
  57783. return var_export($defaultValue, \true);
  57784. }
  57785. $parameterAsString = $parameter->__toString();
  57786. return explode(' = ', substr(substr($parameterAsString, strpos($parameterAsString, '<optional> ') + strlen('<optional> ')), 0, -2))[1];
  57787. // @codeCoverageIgnoreStart
  57788. } catch (\ReflectionException $e) {
  57789. throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
  57790. }
  57791. // @codeCoverageIgnoreEnd
  57792. }
  57793. /**
  57794. * @psalm-return array<int, mixed>
  57795. */
  57796. private static function methodParametersDefaultValues(ReflectionMethod $method): array
  57797. {
  57798. $result = [];
  57799. foreach ($method->getParameters() as $i => $parameter) {
  57800. if (!$parameter->isDefaultValueAvailable()) {
  57801. continue;
  57802. }
  57803. $result[$i] = $parameter->getDefaultValue();
  57804. }
  57805. return $result;
  57806. }
  57807. }
  57808. <?php
  57809. declare (strict_types=1);
  57810. /*
  57811. * This file is part of PHPUnit.
  57812. *
  57813. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57814. *
  57815. * For the full copyright and license information, please view the LICENSE
  57816. * file that was distributed with this source code.
  57817. */
  57818. namespace PHPUnit\Framework\MockObject\Generator;
  57819. use function array_key_exists;
  57820. use function array_values;
  57821. use function strtolower;
  57822. /**
  57823. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57824. *
  57825. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  57826. */
  57827. final class MockMethodSet
  57828. {
  57829. /**
  57830. * @psalm-var array<string,MockMethod>
  57831. */
  57832. private array $methods = [];
  57833. public function addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod ...$methods): void
  57834. {
  57835. foreach ($methods as $method) {
  57836. $this->methods[strtolower($method->methodName())] = $method;
  57837. }
  57838. }
  57839. /**
  57840. * @psalm-return list<MockMethod>
  57841. */
  57842. public function asArray(): array
  57843. {
  57844. return array_values($this->methods);
  57845. }
  57846. public function hasMethod(string $methodName): bool
  57847. {
  57848. return array_key_exists(strtolower($methodName), $this->methods);
  57849. }
  57850. }
  57851. <?php
  57852. declare (strict_types=1);
  57853. /*
  57854. * This file is part of PHPUnit.
  57855. *
  57856. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57857. *
  57858. * For the full copyright and license information, please view the LICENSE
  57859. * file that was distributed with this source code.
  57860. */
  57861. namespace PHPUnit\Framework\MockObject\Generator;
  57862. use function class_exists;
  57863. /**
  57864. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57865. *
  57866. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  57867. *
  57868. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
  57869. */
  57870. final class MockTrait implements \PHPUnit\Framework\MockObject\Generator\MockType
  57871. {
  57872. private readonly string $classCode;
  57873. /**
  57874. * @psalm-var class-string
  57875. */
  57876. private readonly string $mockName;
  57877. /**
  57878. * @psalm-param class-string $mockName
  57879. */
  57880. public function __construct(string $classCode, string $mockName)
  57881. {
  57882. $this->classCode = $classCode;
  57883. $this->mockName = $mockName;
  57884. }
  57885. /**
  57886. * @psalm-return class-string
  57887. */
  57888. public function generate(): string
  57889. {
  57890. if (!class_exists($this->mockName, \false)) {
  57891. eval($this->classCode);
  57892. }
  57893. return $this->mockName;
  57894. }
  57895. }
  57896. <?php
  57897. declare (strict_types=1);
  57898. /*
  57899. * This file is part of PHPUnit.
  57900. *
  57901. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57902. *
  57903. * For the full copyright and license information, please view the LICENSE
  57904. * file that was distributed with this source code.
  57905. */
  57906. namespace PHPUnit\Framework\MockObject\Generator;
  57907. /**
  57908. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57909. *
  57910. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  57911. */
  57912. interface MockType
  57913. {
  57914. /**
  57915. * @psalm-return class-string
  57916. */
  57917. public function generate(): string;
  57918. }
  57919. <?php
  57920. declare (strict_types=1);
  57921. /*
  57922. * This file is part of PHPUnit.
  57923. *
  57924. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57925. *
  57926. * For the full copyright and license information, please view the LICENSE
  57927. * file that was distributed with this source code.
  57928. */
  57929. namespace PHPUnit\Framework\MockObject\Generator;
  57930. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  57931. /**
  57932. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  57933. *
  57934. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  57935. */
  57936. trait TemplateLoader
  57937. {
  57938. /**
  57939. * @psalm-var array<string,Template>
  57940. */
  57941. private static array $templates = [];
  57942. /**
  57943. * @psalm-suppress MissingThrowsDocblock
  57944. */
  57945. private function loadTemplate(string $template): Template
  57946. {
  57947. $filename = __DIR__ . '/templates/' . $template;
  57948. if (!isset(self::$templates[$filename])) {
  57949. self::$templates[$filename] = new Template($filename);
  57950. }
  57951. return self::$templates[$filename];
  57952. }
  57953. }
  57954. @trigger_error({deprecation}, E_USER_DEPRECATED);
  57955. {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
  57956. {{deprecation}
  57957. $__phpunit_definedVariables = get_defined_vars();
  57958. $__phpunit_namedVariadicParameters = [];
  57959. foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) {
  57960. if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) {
  57961. foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) {
  57962. if (is_string($__phpunit_key)) {
  57963. $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue;
  57964. }
  57965. }
  57966. }
  57967. }
  57968. $__phpunit_arguments = [{arguments_call}];
  57969. $__phpunit_count = func_num_args();
  57970. if ({arguments_count} !== null && $__phpunit_count > {arguments_count}) {
  57971. $__phpunit_arguments_tmp = func_get_args();
  57972. for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
  57973. $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
  57974. }
  57975. }
  57976. $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters);
  57977. $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke(
  57978. new \PHPUnit\Framework\MockObject\Invocation(
  57979. '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
  57980. )
  57981. );{return_result}
  57982. }
  57983. {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
  57984. {
  57985. throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object');
  57986. }
  57987. declare(strict_types=1);
  57988. interface {intersection} extends {interfaces}
  57989. {
  57990. }
  57991. {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
  57992. {
  57993. $__phpunit_definedVariables = get_defined_vars();
  57994. $__phpunit_namedVariadicParameters = [];
  57995. foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) {
  57996. if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) {
  57997. foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) {
  57998. if (is_string($__phpunit_key)) {
  57999. $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue;
  58000. }
  58001. }
  58002. }
  58003. }
  58004. $__phpunit_arguments = [{arguments_call}];
  58005. $__phpunit_count = func_num_args();
  58006. if ($__phpunit_count > {arguments_count}) {
  58007. $__phpunit_arguments_tmp = func_get_args();
  58008. for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
  58009. $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
  58010. }
  58011. }
  58012. $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters);
  58013. $this->__phpunit_getInvocationHandler()->invoke(
  58014. new \PHPUnit\Framework\MockObject\Invocation(
  58015. '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true
  58016. )
  58017. );
  58018. $__phpunit_result = call_user_func_array([$this->__phpunit_originalObject, "{method_name}"], $__phpunit_arguments);{return_result}
  58019. }
  58020. declare(strict_types=1);
  58021. {prologue}{class_declaration}
  58022. {
  58023. {use_statements}{mocked_methods}}{epilogue}
  58024. declare(strict_types=1);
  58025. {prologue}class {class_name}
  58026. {
  58027. use {trait_name};
  58028. }
  58029. declare(strict_types=1);
  58030. {namespace}class {class_name} extends \SoapClient
  58031. {
  58032. public function __construct($wsdl, array $options)
  58033. {
  58034. parent::__construct('{wsdl}', $options);
  58035. }
  58036. {methods}}
  58037. public function {method_name}({arguments})
  58038. {
  58039. }
  58040. <?php
  58041. declare (strict_types=1);
  58042. /*
  58043. * This file is part of PHPUnit.
  58044. *
  58045. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58046. *
  58047. * For the full copyright and license information, please view the LICENSE
  58048. * file that was distributed with this source code.
  58049. */
  58050. namespace PHPUnit\Framework\MockObject;
  58051. use function array_merge;
  58052. use function assert;
  58053. use function trait_exists;
  58054. use PHPUnit\Framework\Exception;
  58055. use PHPUnit\Framework\InvalidArgumentException;
  58056. use PHPUnit\Framework\MockObject\Generator\CannotUseAddMethodsException;
  58057. use PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException;
  58058. use PHPUnit\Framework\MockObject\Generator\ClassIsFinalException;
  58059. use PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException;
  58060. use PHPUnit\Framework\MockObject\Generator\DuplicateMethodException;
  58061. use PHPUnit\Framework\MockObject\Generator\Generator;
  58062. use PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException;
  58063. use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
  58064. use PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException;
  58065. use PHPUnit\Framework\MockObject\Generator\ReflectionException;
  58066. use PHPUnit\Framework\MockObject\Generator\RuntimeException;
  58067. use PHPUnit\Framework\MockObject\Generator\UnknownTypeException;
  58068. use PHPUnit\Framework\TestCase;
  58069. use ReflectionClass;
  58070. /**
  58071. * @psalm-template MockedType
  58072. *
  58073. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58074. */
  58075. final class MockBuilder
  58076. {
  58077. private readonly TestCase $testCase;
  58078. /**
  58079. * @psalm-var class-string|trait-string
  58080. */
  58081. private readonly string $type;
  58082. /**
  58083. * @psalm-var list<non-empty-string>
  58084. */
  58085. private array $methods = [];
  58086. private bool $emptyMethodsArray = \false;
  58087. /**
  58088. * @psalm-var ?class-string
  58089. */
  58090. private ?string $mockClassName = null;
  58091. private array $constructorArgs = [];
  58092. private bool $originalConstructor = \true;
  58093. private bool $originalClone = \true;
  58094. private bool $autoload = \true;
  58095. private bool $cloneArguments = \false;
  58096. private bool $callOriginalMethods = \false;
  58097. private ?object $proxyTarget = null;
  58098. private bool $allowMockingUnknownTypes = \true;
  58099. private bool $returnValueGeneration = \true;
  58100. private readonly Generator $generator;
  58101. /**
  58102. * @psalm-param class-string|trait-string $type
  58103. */
  58104. public function __construct(TestCase $testCase, string $type)
  58105. {
  58106. $this->testCase = $testCase;
  58107. $this->type = $type;
  58108. $this->generator = new Generator();
  58109. }
  58110. /**
  58111. * Creates a mock object using a fluent interface.
  58112. *
  58113. * @throws ClassIsEnumerationException
  58114. * @throws ClassIsFinalException
  58115. * @throws ClassIsReadonlyException
  58116. * @throws DuplicateMethodException
  58117. * @throws InvalidArgumentException
  58118. * @throws InvalidMethodNameException
  58119. * @throws NameAlreadyInUseException
  58120. * @throws OriginalConstructorInvocationRequiredException
  58121. * @throws ReflectionException
  58122. * @throws RuntimeException
  58123. * @throws UnknownTypeException
  58124. *
  58125. * @psalm-return MockObject&MockedType
  58126. */
  58127. public function getMock(): \PHPUnit\Framework\MockObject\MockObject
  58128. {
  58129. $object = $this->generator->testDouble($this->type, \true, !$this->emptyMethodsArray ? $this->methods : null, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->cloneArguments, $this->callOriginalMethods, $this->proxyTarget, $this->allowMockingUnknownTypes, $this->returnValueGeneration);
  58130. assert($object instanceof $this->type);
  58131. assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
  58132. $this->testCase->registerMockObject($object);
  58133. return $object;
  58134. }
  58135. /**
  58136. * Creates a mock object for an abstract class using a fluent interface.
  58137. *
  58138. * @psalm-return MockObject&MockedType
  58139. *
  58140. * @throws Exception
  58141. * @throws ReflectionException
  58142. * @throws RuntimeException
  58143. *
  58144. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5305
  58145. */
  58146. public function getMockForAbstractClass(): \PHPUnit\Framework\MockObject\MockObject
  58147. {
  58148. $object = $this->generator->mockObjectForAbstractClass($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments);
  58149. assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
  58150. $this->testCase->registerMockObject($object);
  58151. return $object;
  58152. }
  58153. /**
  58154. * Creates a mock object for a trait using a fluent interface.
  58155. *
  58156. * @psalm-return MockObject&MockedType
  58157. *
  58158. * @throws Exception
  58159. * @throws ReflectionException
  58160. * @throws RuntimeException
  58161. *
  58162. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5306
  58163. */
  58164. public function getMockForTrait(): \PHPUnit\Framework\MockObject\MockObject
  58165. {
  58166. assert(trait_exists($this->type));
  58167. $object = $this->generator->mockObjectForTrait($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments);
  58168. assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
  58169. $this->testCase->registerMockObject($object);
  58170. return $object;
  58171. }
  58172. /**
  58173. * Specifies the subset of methods to mock, requiring each to exist in the class.
  58174. *
  58175. * @psalm-param list<non-empty-string> $methods
  58176. *
  58177. * @throws CannotUseOnlyMethodsException
  58178. * @throws ReflectionException
  58179. *
  58180. * @return $this
  58181. */
  58182. public function onlyMethods(array $methods): self
  58183. {
  58184. if (empty($methods)) {
  58185. $this->emptyMethodsArray = \true;
  58186. return $this;
  58187. }
  58188. try {
  58189. $reflector = new ReflectionClass($this->type);
  58190. // @codeCoverageIgnoreStart
  58191. } catch (\ReflectionException $e) {
  58192. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  58193. // @codeCoverageIgnoreEnd
  58194. }
  58195. foreach ($methods as $method) {
  58196. if (!$reflector->hasMethod($method)) {
  58197. throw new \PHPUnit\Framework\MockObject\CannotUseOnlyMethodsException($this->type, $method);
  58198. }
  58199. }
  58200. $this->methods = array_merge($this->methods, $methods);
  58201. return $this;
  58202. }
  58203. /**
  58204. * Specifies methods that don't exist in the class which you want to mock.
  58205. *
  58206. * @psalm-param list<non-empty-string> $methods
  58207. *
  58208. * @throws CannotUseAddMethodsException
  58209. * @throws ReflectionException
  58210. * @throws RuntimeException
  58211. *
  58212. * @return $this
  58213. *
  58214. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5320
  58215. */
  58216. public function addMethods(array $methods): self
  58217. {
  58218. if (empty($methods)) {
  58219. $this->emptyMethodsArray = \true;
  58220. return $this;
  58221. }
  58222. try {
  58223. $reflector = new ReflectionClass($this->type);
  58224. // @codeCoverageIgnoreStart
  58225. } catch (\ReflectionException $e) {
  58226. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  58227. // @codeCoverageIgnoreEnd
  58228. }
  58229. foreach ($methods as $method) {
  58230. if ($reflector->hasMethod($method)) {
  58231. throw new CannotUseAddMethodsException($this->type, $method);
  58232. }
  58233. }
  58234. $this->methods = array_merge($this->methods, $methods);
  58235. return $this;
  58236. }
  58237. /**
  58238. * Specifies the arguments for the constructor.
  58239. *
  58240. * @return $this
  58241. */
  58242. public function setConstructorArgs(array $arguments): self
  58243. {
  58244. $this->constructorArgs = $arguments;
  58245. return $this;
  58246. }
  58247. /**
  58248. * Specifies the name for the mock class.
  58249. *
  58250. * @psalm-param class-string $name
  58251. *
  58252. * @return $this
  58253. */
  58254. public function setMockClassName(string $name): self
  58255. {
  58256. $this->mockClassName = $name;
  58257. return $this;
  58258. }
  58259. /**
  58260. * Disables the invocation of the original constructor.
  58261. *
  58262. * @return $this
  58263. */
  58264. public function disableOriginalConstructor(): self
  58265. {
  58266. $this->originalConstructor = \false;
  58267. return $this;
  58268. }
  58269. /**
  58270. * Enables the invocation of the original constructor.
  58271. *
  58272. * @return $this
  58273. */
  58274. public function enableOriginalConstructor(): self
  58275. {
  58276. $this->originalConstructor = \true;
  58277. return $this;
  58278. }
  58279. /**
  58280. * Disables the invocation of the original clone constructor.
  58281. *
  58282. * @return $this
  58283. */
  58284. public function disableOriginalClone(): self
  58285. {
  58286. $this->originalClone = \false;
  58287. return $this;
  58288. }
  58289. /**
  58290. * Enables the invocation of the original clone constructor.
  58291. *
  58292. * @return $this
  58293. */
  58294. public function enableOriginalClone(): self
  58295. {
  58296. $this->originalClone = \true;
  58297. return $this;
  58298. }
  58299. /**
  58300. * Disables the use of class autoloading while creating the mock object.
  58301. *
  58302. * @return $this
  58303. *
  58304. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309
  58305. *
  58306. * @codeCoverageIgnore
  58307. */
  58308. public function disableAutoload(): self
  58309. {
  58310. $this->autoload = \false;
  58311. return $this;
  58312. }
  58313. /**
  58314. * Enables the use of class autoloading while creating the mock object.
  58315. *
  58316. * @return $this
  58317. *
  58318. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309
  58319. */
  58320. public function enableAutoload(): self
  58321. {
  58322. $this->autoload = \true;
  58323. return $this;
  58324. }
  58325. /**
  58326. * Disables the cloning of arguments passed to mocked methods.
  58327. *
  58328. * @return $this
  58329. *
  58330. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315
  58331. */
  58332. public function disableArgumentCloning(): self
  58333. {
  58334. $this->cloneArguments = \false;
  58335. return $this;
  58336. }
  58337. /**
  58338. * Enables the cloning of arguments passed to mocked methods.
  58339. *
  58340. * @return $this
  58341. *
  58342. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315
  58343. */
  58344. public function enableArgumentCloning(): self
  58345. {
  58346. $this->cloneArguments = \true;
  58347. return $this;
  58348. }
  58349. /**
  58350. * Enables the invocation of the original methods.
  58351. *
  58352. * @return $this
  58353. *
  58354. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
  58355. *
  58356. * @codeCoverageIgnore
  58357. */
  58358. public function enableProxyingToOriginalMethods(): self
  58359. {
  58360. $this->callOriginalMethods = \true;
  58361. return $this;
  58362. }
  58363. /**
  58364. * Disables the invocation of the original methods.
  58365. *
  58366. * @return $this
  58367. *
  58368. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
  58369. */
  58370. public function disableProxyingToOriginalMethods(): self
  58371. {
  58372. $this->callOriginalMethods = \false;
  58373. $this->proxyTarget = null;
  58374. return $this;
  58375. }
  58376. /**
  58377. * Sets the proxy target.
  58378. *
  58379. * @return $this
  58380. *
  58381. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
  58382. *
  58383. * @codeCoverageIgnore
  58384. */
  58385. public function setProxyTarget(object $object): self
  58386. {
  58387. $this->proxyTarget = $object;
  58388. return $this;
  58389. }
  58390. /**
  58391. * @return $this
  58392. *
  58393. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308
  58394. */
  58395. public function allowMockingUnknownTypes(): self
  58396. {
  58397. $this->allowMockingUnknownTypes = \true;
  58398. return $this;
  58399. }
  58400. /**
  58401. * @return $this
  58402. *
  58403. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308
  58404. */
  58405. public function disallowMockingUnknownTypes(): self
  58406. {
  58407. $this->allowMockingUnknownTypes = \false;
  58408. return $this;
  58409. }
  58410. /**
  58411. * @return $this
  58412. */
  58413. public function enableAutoReturnValueGeneration(): self
  58414. {
  58415. $this->returnValueGeneration = \true;
  58416. return $this;
  58417. }
  58418. /**
  58419. * @return $this
  58420. */
  58421. public function disableAutoReturnValueGeneration(): self
  58422. {
  58423. $this->returnValueGeneration = \false;
  58424. return $this;
  58425. }
  58426. }
  58427. <?php
  58428. declare (strict_types=1);
  58429. /*
  58430. * This file is part of PHPUnit.
  58431. *
  58432. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58433. *
  58434. * For the full copyright and license information, please view the LICENSE
  58435. * file that was distributed with this source code.
  58436. */
  58437. namespace PHPUnit\Framework\MockObject;
  58438. /**
  58439. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58440. *
  58441. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  58442. */
  58443. trait DoubledCloneMethod
  58444. {
  58445. public function __clone(): void
  58446. {
  58447. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
  58448. }
  58449. }
  58450. <?php
  58451. declare (strict_types=1);
  58452. /*
  58453. * This file is part of PHPUnit.
  58454. *
  58455. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58456. *
  58457. * For the full copyright and license information, please view the LICENSE
  58458. * file that was distributed with this source code.
  58459. */
  58460. namespace PHPUnit\Framework\MockObject;
  58461. use function call_user_func_array;
  58462. use function func_get_args;
  58463. use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
  58464. use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
  58465. /**
  58466. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58467. *
  58468. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  58469. */
  58470. trait Method
  58471. {
  58472. public function method(): InvocationMocker
  58473. {
  58474. $expects = $this->expects(new AnyInvokedCount());
  58475. return call_user_func_array([$expects, 'method'], func_get_args());
  58476. }
  58477. }
  58478. <?php
  58479. declare (strict_types=1);
  58480. /*
  58481. * This file is part of PHPUnit.
  58482. *
  58483. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58484. *
  58485. * For the full copyright and license information, please view the LICENSE
  58486. * file that was distributed with this source code.
  58487. */
  58488. namespace PHPUnit\Framework\MockObject;
  58489. use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder;
  58490. use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
  58491. /**
  58492. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58493. *
  58494. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  58495. */
  58496. trait MockObjectApi
  58497. {
  58498. private object $__phpunit_originalObject;
  58499. /** @noinspection MagicMethodsValidityInspection */
  58500. public function __phpunit_hasMatchers(): bool
  58501. {
  58502. return $this->__phpunit_getInvocationHandler()->hasMatchers();
  58503. }
  58504. /** @noinspection MagicMethodsValidityInspection */
  58505. public function __phpunit_setOriginalObject(object $originalObject): void
  58506. {
  58507. $this->__phpunit_originalObject = $originalObject;
  58508. }
  58509. /** @noinspection MagicMethodsValidityInspection */
  58510. public function __phpunit_verify(bool $unsetInvocationMocker = \true): void
  58511. {
  58512. $this->__phpunit_getInvocationHandler()->verify();
  58513. if ($unsetInvocationMocker) {
  58514. $this->__phpunit_unsetInvocationMocker();
  58515. }
  58516. }
  58517. abstract public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler;
  58518. abstract public function __phpunit_unsetInvocationMocker(): void;
  58519. public function expects(InvocationOrder $matcher): InvocationMockerBuilder
  58520. {
  58521. return $this->__phpunit_getInvocationHandler()->expects($matcher);
  58522. }
  58523. }
  58524. <?php
  58525. declare (strict_types=1);
  58526. /*
  58527. * This file is part of PHPUnit.
  58528. *
  58529. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58530. *
  58531. * For the full copyright and license information, please view the LICENSE
  58532. * file that was distributed with this source code.
  58533. */
  58534. namespace PHPUnit\Framework\MockObject;
  58535. /**
  58536. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58537. *
  58538. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  58539. */
  58540. trait ProxiedCloneMethod
  58541. {
  58542. public function __clone(): void
  58543. {
  58544. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
  58545. parent::__clone();
  58546. }
  58547. }
  58548. <?php
  58549. declare (strict_types=1);
  58550. /*
  58551. * This file is part of PHPUnit.
  58552. *
  58553. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58554. *
  58555. * For the full copyright and license information, please view the LICENSE
  58556. * file that was distributed with this source code.
  58557. */
  58558. namespace PHPUnit\Framework\MockObject;
  58559. /**
  58560. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58561. *
  58562. * @internal This trait is not covered by the backward compatibility promise for PHPUnit
  58563. */
  58564. trait StubApi
  58565. {
  58566. /**
  58567. * @psalm-var list<ConfigurableMethod>
  58568. */
  58569. private static array $__phpunit_configurableMethods;
  58570. private bool $__phpunit_returnValueGeneration = \true;
  58571. private ?\PHPUnit\Framework\MockObject\InvocationHandler $__phpunit_invocationMocker = null;
  58572. /** @noinspection MagicMethodsValidityInspection */
  58573. public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods): void
  58574. {
  58575. static::$__phpunit_configurableMethods = $configurableMethods;
  58576. }
  58577. /** @noinspection MagicMethodsValidityInspection */
  58578. public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void
  58579. {
  58580. $this->__phpunit_returnValueGeneration = $returnValueGeneration;
  58581. }
  58582. /** @noinspection MagicMethodsValidityInspection */
  58583. public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler
  58584. {
  58585. if ($this->__phpunit_invocationMocker === null) {
  58586. $this->__phpunit_invocationMocker = new \PHPUnit\Framework\MockObject\InvocationHandler(static::$__phpunit_configurableMethods, $this->__phpunit_returnValueGeneration);
  58587. }
  58588. return $this->__phpunit_invocationMocker;
  58589. }
  58590. /** @noinspection MagicMethodsValidityInspection */
  58591. public function __phpunit_unsetInvocationMocker(): void
  58592. {
  58593. $this->__phpunit_invocationMocker = null;
  58594. }
  58595. }
  58596. <?php
  58597. declare (strict_types=1);
  58598. /*
  58599. * This file is part of PHPUnit.
  58600. *
  58601. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58602. *
  58603. * For the full copyright and license information, please view the LICENSE
  58604. * file that was distributed with this source code.
  58605. */
  58606. namespace PHPUnit\Framework\MockObject\Builder;
  58607. /**
  58608. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58609. *
  58610. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  58611. */
  58612. interface Identity
  58613. {
  58614. /**
  58615. * Sets the identification of the expectation to $id.
  58616. *
  58617. * @note The identifier is unique per mock object.
  58618. */
  58619. public function id(string $id): self;
  58620. }
  58621. <?php
  58622. declare (strict_types=1);
  58623. /*
  58624. * This file is part of PHPUnit.
  58625. *
  58626. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58627. *
  58628. * For the full copyright and license information, please view the LICENSE
  58629. * file that was distributed with this source code.
  58630. */
  58631. namespace PHPUnit\Framework\MockObject\Builder;
  58632. use function array_flip;
  58633. use function array_key_exists;
  58634. use function array_map;
  58635. use function array_merge;
  58636. use function array_pop;
  58637. use function assert;
  58638. use function count;
  58639. use function is_string;
  58640. use function range;
  58641. use function strtolower;
  58642. use PHPUnit\Framework\Constraint\Constraint;
  58643. use PHPUnit\Framework\InvalidArgumentException;
  58644. use PHPUnit\Framework\MockObject\ConfigurableMethod;
  58645. use PHPUnit\Framework\MockObject\IncompatibleReturnValueException;
  58646. use PHPUnit\Framework\MockObject\InvocationHandler;
  58647. use PHPUnit\Framework\MockObject\Matcher;
  58648. use PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException;
  58649. use PHPUnit\Framework\MockObject\MethodCannotBeConfiguredException;
  58650. use PHPUnit\Framework\MockObject\MethodNameAlreadyConfiguredException;
  58651. use PHPUnit\Framework\MockObject\MethodNameNotConfiguredException;
  58652. use PHPUnit\Framework\MockObject\MethodParametersAlreadyConfiguredException;
  58653. use PHPUnit\Framework\MockObject\Rule;
  58654. use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls;
  58655. use PHPUnit\Framework\MockObject\Stub\Exception;
  58656. use PHPUnit\Framework\MockObject\Stub\ReturnArgument;
  58657. use PHPUnit\Framework\MockObject\Stub\ReturnCallback;
  58658. use PHPUnit\Framework\MockObject\Stub\ReturnReference;
  58659. use PHPUnit\Framework\MockObject\Stub\ReturnSelf;
  58660. use PHPUnit\Framework\MockObject\Stub\ReturnStub;
  58661. use PHPUnit\Framework\MockObject\Stub\ReturnValueMap;
  58662. use PHPUnit\Framework\MockObject\Stub\Stub;
  58663. use Throwable;
  58664. /**
  58665. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58666. */
  58667. final class InvocationMocker implements \PHPUnit\Framework\MockObject\Builder\InvocationStubber, \PHPUnit\Framework\MockObject\Builder\MethodNameMatch
  58668. {
  58669. private readonly InvocationHandler $invocationHandler;
  58670. private readonly Matcher $matcher;
  58671. /**
  58672. * @psalm-var list<ConfigurableMethod>
  58673. */
  58674. private readonly array $configurableMethods;
  58675. /**
  58676. * @psalm-var ?array<string, int>
  58677. */
  58678. private ?array $configurableMethodNames = null;
  58679. public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods)
  58680. {
  58681. $this->invocationHandler = $handler;
  58682. $this->matcher = $matcher;
  58683. $this->configurableMethods = $configurableMethods;
  58684. }
  58685. /**
  58686. * @throws MatcherAlreadyRegisteredException
  58687. *
  58688. * @return $this
  58689. */
  58690. public function id(string $id): self
  58691. {
  58692. $this->invocationHandler->registerMatcher($id, $this->matcher);
  58693. return $this;
  58694. }
  58695. /**
  58696. * @return $this
  58697. */
  58698. public function will(Stub $stub): \PHPUnit\Framework\MockObject\Builder\Identity
  58699. {
  58700. $this->matcher->setStub($stub);
  58701. return $this;
  58702. }
  58703. /**
  58704. * @throws IncompatibleReturnValueException
  58705. */
  58706. public function willReturn(mixed $value, mixed ...$nextValues): self
  58707. {
  58708. if (count($nextValues) === 0) {
  58709. $this->ensureTypeOfReturnValues([$value]);
  58710. $stub = $value instanceof Stub ? $value : new ReturnStub($value);
  58711. return $this->will($stub);
  58712. }
  58713. $values = array_merge([$value], $nextValues);
  58714. $this->ensureTypeOfReturnValues($values);
  58715. $stub = new ConsecutiveCalls($values);
  58716. return $this->will($stub);
  58717. }
  58718. public function willReturnReference(mixed &$reference): self
  58719. {
  58720. $stub = new ReturnReference($reference);
  58721. return $this->will($stub);
  58722. }
  58723. public function willReturnMap(array $valueMap): self
  58724. {
  58725. $method = $this->configuredMethod();
  58726. assert($method instanceof ConfigurableMethod);
  58727. $numberOfParameters = $method->numberOfParameters();
  58728. $defaultValues = $method->defaultParameterValues();
  58729. $hasDefaultValues = !empty($defaultValues);
  58730. $_valueMap = [];
  58731. foreach ($valueMap as $mapping) {
  58732. $numberOfConfiguredParameters = count($mapping) - 1;
  58733. if ($numberOfConfiguredParameters === $numberOfParameters || !$hasDefaultValues) {
  58734. $_valueMap[] = $mapping;
  58735. continue;
  58736. }
  58737. $_mapping = [];
  58738. $returnValue = array_pop($mapping);
  58739. foreach (range(0, $numberOfParameters - 1) as $i) {
  58740. if (isset($mapping[$i])) {
  58741. $_mapping[] = $mapping[$i];
  58742. continue;
  58743. }
  58744. if (isset($defaultValues[$i])) {
  58745. $_mapping[] = $defaultValues[$i];
  58746. }
  58747. }
  58748. $_mapping[] = $returnValue;
  58749. $_valueMap[] = $_mapping;
  58750. }
  58751. $stub = new ReturnValueMap($_valueMap);
  58752. return $this->will($stub);
  58753. }
  58754. public function willReturnArgument(int $argumentIndex): self
  58755. {
  58756. $stub = new ReturnArgument($argumentIndex);
  58757. return $this->will($stub);
  58758. }
  58759. public function willReturnCallback(callable $callback): self
  58760. {
  58761. $stub = new ReturnCallback($callback);
  58762. return $this->will($stub);
  58763. }
  58764. public function willReturnSelf(): self
  58765. {
  58766. $stub = new ReturnSelf();
  58767. return $this->will($stub);
  58768. }
  58769. public function willReturnOnConsecutiveCalls(mixed ...$values): self
  58770. {
  58771. $stub = new ConsecutiveCalls($values);
  58772. return $this->will($stub);
  58773. }
  58774. public function willThrowException(Throwable $exception): self
  58775. {
  58776. $stub = new Exception($exception);
  58777. return $this->will($stub);
  58778. }
  58779. /**
  58780. * @return $this
  58781. */
  58782. public function after(string $id): self
  58783. {
  58784. $this->matcher->setAfterMatchBuilderId($id);
  58785. return $this;
  58786. }
  58787. /**
  58788. * @throws \PHPUnit\Framework\Exception
  58789. * @throws MethodNameNotConfiguredException
  58790. * @throws MethodParametersAlreadyConfiguredException
  58791. *
  58792. * @return $this
  58793. */
  58794. public function with(mixed ...$arguments): self
  58795. {
  58796. $this->ensureParametersCanBeConfigured();
  58797. $this->matcher->setParametersRule(new Rule\Parameters($arguments));
  58798. return $this;
  58799. }
  58800. /**
  58801. * @throws MethodNameNotConfiguredException
  58802. * @throws MethodParametersAlreadyConfiguredException
  58803. *
  58804. * @return $this
  58805. */
  58806. public function withAnyParameters(): self
  58807. {
  58808. $this->ensureParametersCanBeConfigured();
  58809. $this->matcher->setParametersRule(new Rule\AnyParameters());
  58810. return $this;
  58811. }
  58812. /**
  58813. * @throws InvalidArgumentException
  58814. * @throws MethodCannotBeConfiguredException
  58815. * @throws MethodNameAlreadyConfiguredException
  58816. *
  58817. * @return $this
  58818. */
  58819. public function method(Constraint|string $constraint): self
  58820. {
  58821. if ($this->matcher->hasMethodNameRule()) {
  58822. throw new MethodNameAlreadyConfiguredException();
  58823. }
  58824. if (is_string($constraint)) {
  58825. $this->configurableMethodNames ??= array_flip(array_map(static fn(ConfigurableMethod $configurable) => strtolower($configurable->name()), $this->configurableMethods));
  58826. if (!array_key_exists(strtolower($constraint), $this->configurableMethodNames)) {
  58827. throw new MethodCannotBeConfiguredException($constraint);
  58828. }
  58829. }
  58830. $this->matcher->setMethodNameRule(new Rule\MethodName($constraint));
  58831. return $this;
  58832. }
  58833. /**
  58834. * @throws MethodNameNotConfiguredException
  58835. * @throws MethodParametersAlreadyConfiguredException
  58836. */
  58837. private function ensureParametersCanBeConfigured(): void
  58838. {
  58839. if (!$this->matcher->hasMethodNameRule()) {
  58840. throw new MethodNameNotConfiguredException();
  58841. }
  58842. if ($this->matcher->hasParametersRule()) {
  58843. throw new MethodParametersAlreadyConfiguredException();
  58844. }
  58845. }
  58846. private function configuredMethod(): ?ConfigurableMethod
  58847. {
  58848. $configuredMethod = null;
  58849. foreach ($this->configurableMethods as $configurableMethod) {
  58850. if ($this->matcher->methodNameRule()->matchesName($configurableMethod->name())) {
  58851. if ($configuredMethod !== null) {
  58852. return null;
  58853. }
  58854. $configuredMethod = $configurableMethod;
  58855. }
  58856. }
  58857. return $configuredMethod;
  58858. }
  58859. /**
  58860. * @throws IncompatibleReturnValueException
  58861. */
  58862. private function ensureTypeOfReturnValues(array $values): void
  58863. {
  58864. $configuredMethod = $this->configuredMethod();
  58865. if ($configuredMethod === null) {
  58866. return;
  58867. }
  58868. foreach ($values as $value) {
  58869. if (!$configuredMethod->mayReturn($value)) {
  58870. throw new IncompatibleReturnValueException($configuredMethod, $value);
  58871. }
  58872. }
  58873. }
  58874. }
  58875. <?php
  58876. declare (strict_types=1);
  58877. /*
  58878. * This file is part of PHPUnit.
  58879. *
  58880. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58881. *
  58882. * For the full copyright and license information, please view the LICENSE
  58883. * file that was distributed with this source code.
  58884. */
  58885. namespace PHPUnit\Framework\MockObject\Builder;
  58886. use PHPUnit\Framework\MockObject\Stub\Stub;
  58887. use Throwable;
  58888. /**
  58889. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58890. */
  58891. interface InvocationStubber
  58892. {
  58893. public function will(Stub $stub): \PHPUnit\Framework\MockObject\Builder\Identity;
  58894. public function willReturn(mixed $value, mixed ...$nextValues): self;
  58895. public function willReturnReference(mixed &$reference): self;
  58896. /**
  58897. * @psalm-param array<int, array<int, mixed>> $valueMap
  58898. */
  58899. public function willReturnMap(array $valueMap): self;
  58900. public function willReturnArgument(int $argumentIndex): self;
  58901. public function willReturnCallback(callable $callback): self;
  58902. public function willReturnSelf(): self;
  58903. public function willReturnOnConsecutiveCalls(mixed ...$values): self;
  58904. public function willThrowException(Throwable $exception): self;
  58905. }
  58906. <?php
  58907. declare (strict_types=1);
  58908. /*
  58909. * This file is part of PHPUnit.
  58910. *
  58911. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58912. *
  58913. * For the full copyright and license information, please view the LICENSE
  58914. * file that was distributed with this source code.
  58915. */
  58916. namespace PHPUnit\Framework\MockObject\Builder;
  58917. use PHPUnit\Framework\Constraint\Constraint;
  58918. /**
  58919. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58920. *
  58921. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  58922. */
  58923. interface MethodNameMatch extends \PHPUnit\Framework\MockObject\Builder\ParametersMatch
  58924. {
  58925. /**
  58926. * Adds a new method name match and returns the parameter match object for
  58927. * further matching possibilities.
  58928. */
  58929. public function method(Constraint|string $constraint): self;
  58930. }
  58931. <?php
  58932. declare (strict_types=1);
  58933. /*
  58934. * This file is part of PHPUnit.
  58935. *
  58936. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58937. *
  58938. * For the full copyright and license information, please view the LICENSE
  58939. * file that was distributed with this source code.
  58940. */
  58941. namespace PHPUnit\Framework\MockObject\Builder;
  58942. /**
  58943. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58944. *
  58945. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  58946. */
  58947. interface ParametersMatch extends \PHPUnit\Framework\MockObject\Builder\Stub
  58948. {
  58949. /**
  58950. * Defines the expectation which must occur before the current is valid.
  58951. */
  58952. public function after(string $id): \PHPUnit\Framework\MockObject\Builder\Stub;
  58953. /**
  58954. * Sets the parameters to match for, each parameter to this function will
  58955. * be part of match. To perform specific matches or constraints create a
  58956. * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter.
  58957. * If the parameter value is not a constraint it will use the
  58958. * PHPUnit\Framework\Constraint\IsEqual for the value.
  58959. *
  58960. * Some examples:
  58961. * <code>
  58962. * // match first parameter with value 2
  58963. * $b->with(2);
  58964. * // match first parameter with value 'smock' and second identical to 42
  58965. * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42));
  58966. * </code>
  58967. */
  58968. public function with(mixed ...$arguments): self;
  58969. /**
  58970. * Sets a rule which allows any kind of parameters.
  58971. *
  58972. * Some examples:
  58973. * <code>
  58974. * // match any number of parameters
  58975. * $b->withAnyParameters();
  58976. * </code>
  58977. */
  58978. public function withAnyParameters(): self;
  58979. }
  58980. <?php
  58981. declare (strict_types=1);
  58982. /*
  58983. * This file is part of PHPUnit.
  58984. *
  58985. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58986. *
  58987. * For the full copyright and license information, please view the LICENSE
  58988. * file that was distributed with this source code.
  58989. */
  58990. namespace PHPUnit\Framework\MockObject\Builder;
  58991. use PHPUnit\Framework\MockObject\Stub\Stub as BaseStub;
  58992. /**
  58993. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  58994. *
  58995. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  58996. */
  58997. interface Stub extends \PHPUnit\Framework\MockObject\Builder\Identity
  58998. {
  58999. /**
  59000. * Stubs the matching method with the stub object $stub. Any invocations of
  59001. * the matched method will now be handled by the stub instead.
  59002. */
  59003. public function will(BaseStub $stub): \PHPUnit\Framework\MockObject\Builder\Identity;
  59004. }
  59005. <?php
  59006. declare (strict_types=1);
  59007. /*
  59008. * This file is part of PHPUnit.
  59009. *
  59010. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59011. *
  59012. * For the full copyright and license information, please view the LICENSE
  59013. * file that was distributed with this source code.
  59014. */
  59015. namespace PHPUnit\Framework\MockObject;
  59016. use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
  59017. use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
  59018. /**
  59019. * @method InvocationMocker method($constraint)
  59020. *
  59021. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59022. */
  59023. interface MockObject extends \PHPUnit\Framework\MockObject\Stub
  59024. {
  59025. public function expects(InvocationOrder $invocationRule): InvocationMocker;
  59026. }
  59027. <?php
  59028. declare (strict_types=1);
  59029. /*
  59030. * This file is part of PHPUnit.
  59031. *
  59032. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59033. *
  59034. * For the full copyright and license information, please view the LICENSE
  59035. * file that was distributed with this source code.
  59036. */
  59037. namespace PHPUnit\Framework\MockObject;
  59038. /**
  59039. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59040. *
  59041. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  59042. */
  59043. interface MockObjectInternal extends \PHPUnit\Framework\MockObject\MockObject, \PHPUnit\Framework\MockObject\StubInternal
  59044. {
  59045. public function __phpunit_hasMatchers(): bool;
  59046. public function __phpunit_setOriginalObject(object $originalObject): void;
  59047. public function __phpunit_verify(bool $unsetInvocationMocker = \true): void;
  59048. }
  59049. <?php
  59050. declare (strict_types=1);
  59051. /*
  59052. * This file is part of PHPUnit.
  59053. *
  59054. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59055. *
  59056. * For the full copyright and license information, please view the LICENSE
  59057. * file that was distributed with this source code.
  59058. */
  59059. namespace PHPUnit\Framework\MockObject;
  59060. use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
  59061. /**
  59062. * @method InvocationStubber method($constraint)
  59063. *
  59064. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59065. */
  59066. interface Stub
  59067. {
  59068. }
  59069. <?php
  59070. declare (strict_types=1);
  59071. /*
  59072. * This file is part of PHPUnit.
  59073. *
  59074. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59075. *
  59076. * For the full copyright and license information, please view the LICENSE
  59077. * file that was distributed with this source code.
  59078. */
  59079. namespace PHPUnit\Framework\MockObject;
  59080. /**
  59081. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59082. *
  59083. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  59084. */
  59085. interface StubInternal extends \PHPUnit\Framework\MockObject\Stub
  59086. {
  59087. public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods): void;
  59088. public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler;
  59089. public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void;
  59090. public function __phpunit_unsetInvocationMocker(): void;
  59091. }
  59092. <?php
  59093. declare (strict_types=1);
  59094. /*
  59095. * This file is part of PHPUnit.
  59096. *
  59097. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59098. *
  59099. * For the full copyright and license information, please view the LICENSE
  59100. * file that was distributed with this source code.
  59101. */
  59102. namespace PHPUnit\Framework\MockObject;
  59103. use function array_map;
  59104. use function implode;
  59105. use function is_object;
  59106. use function sprintf;
  59107. use function str_starts_with;
  59108. use function strtolower;
  59109. use function substr;
  59110. use PHPUnit\Framework\SelfDescribing;
  59111. use PHPUnit\Util\Cloner;
  59112. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  59113. /**
  59114. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59115. *
  59116. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59117. */
  59118. final class Invocation implements SelfDescribing
  59119. {
  59120. /**
  59121. * @psalm-var class-string
  59122. */
  59123. private readonly string $className;
  59124. /**
  59125. * @psalm-var non-empty-string
  59126. */
  59127. private readonly string $methodName;
  59128. private readonly array $parameters;
  59129. private readonly string $returnType;
  59130. private readonly bool $isReturnTypeNullable;
  59131. private readonly bool $proxiedCall;
  59132. private readonly \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal $object;
  59133. /**
  59134. * @psalm-param class-string $className
  59135. * @psalm-param non-empty-string $methodName
  59136. */
  59137. public function __construct(string $className, string $methodName, array $parameters, string $returnType, \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal $object, bool $cloneObjects = \false, bool $proxiedCall = \false)
  59138. {
  59139. $this->className = $className;
  59140. $this->methodName = $methodName;
  59141. $this->object = $object;
  59142. $this->proxiedCall = $proxiedCall;
  59143. if (strtolower($methodName) === '__tostring') {
  59144. $returnType = 'string';
  59145. }
  59146. if (str_starts_with($returnType, '?')) {
  59147. $returnType = substr($returnType, 1);
  59148. $this->isReturnTypeNullable = \true;
  59149. } else {
  59150. $this->isReturnTypeNullable = \false;
  59151. }
  59152. $this->returnType = $returnType;
  59153. if (!$cloneObjects) {
  59154. $this->parameters = $parameters;
  59155. return;
  59156. }
  59157. foreach ($parameters as $key => $value) {
  59158. if (is_object($value)) {
  59159. $parameters[$key] = Cloner::clone($value);
  59160. }
  59161. }
  59162. $this->parameters = $parameters;
  59163. }
  59164. /**
  59165. * @psalm-return class-string
  59166. */
  59167. public function className(): string
  59168. {
  59169. return $this->className;
  59170. }
  59171. /**
  59172. * @psalm-return non-empty-string
  59173. */
  59174. public function methodName(): string
  59175. {
  59176. return $this->methodName;
  59177. }
  59178. public function parameters(): array
  59179. {
  59180. return $this->parameters;
  59181. }
  59182. /**
  59183. * @throws Exception
  59184. */
  59185. public function generateReturnValue(): mixed
  59186. {
  59187. if ($this->returnType === 'never') {
  59188. throw new \PHPUnit\Framework\MockObject\NeverReturningMethodException($this->className, $this->methodName);
  59189. }
  59190. if ($this->isReturnTypeNullable || $this->proxiedCall) {
  59191. return null;
  59192. }
  59193. return (new \PHPUnit\Framework\MockObject\ReturnValueGenerator())->generate($this->className, $this->methodName, $this->object::class, $this->returnType);
  59194. }
  59195. public function toString(): string
  59196. {
  59197. $exporter = new Exporter();
  59198. return sprintf('%s::%s(%s)%s', $this->className, $this->methodName, implode(', ', array_map([$exporter, 'shortenedExport'], $this->parameters)), $this->returnType ? sprintf(': %s', $this->returnType) : '');
  59199. }
  59200. public function object(): \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal
  59201. {
  59202. return $this->object;
  59203. }
  59204. }
  59205. <?php
  59206. declare (strict_types=1);
  59207. /*
  59208. * This file is part of PHPUnit.
  59209. *
  59210. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59211. *
  59212. * For the full copyright and license information, please view the LICENSE
  59213. * file that was distributed with this source code.
  59214. */
  59215. namespace PHPUnit\Framework\MockObject;
  59216. use function strtolower;
  59217. use Exception;
  59218. use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
  59219. use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
  59220. use Throwable;
  59221. /**
  59222. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59223. *
  59224. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59225. */
  59226. final class InvocationHandler
  59227. {
  59228. /**
  59229. * @psalm-var list<Matcher>
  59230. */
  59231. private array $matchers = [];
  59232. /**
  59233. * @psalm-var array<string,Matcher>
  59234. */
  59235. private array $matcherMap = [];
  59236. /**
  59237. * @psalm-var list<ConfigurableMethod>
  59238. */
  59239. private readonly array $configurableMethods;
  59240. private readonly bool $returnValueGeneration;
  59241. /**
  59242. * @psalm-param list<ConfigurableMethod> $configurableMethods
  59243. */
  59244. public function __construct(array $configurableMethods, bool $returnValueGeneration)
  59245. {
  59246. $this->configurableMethods = $configurableMethods;
  59247. $this->returnValueGeneration = $returnValueGeneration;
  59248. }
  59249. public function hasMatchers(): bool
  59250. {
  59251. foreach ($this->matchers as $matcher) {
  59252. if ($matcher->hasMatchers()) {
  59253. return \true;
  59254. }
  59255. }
  59256. return \false;
  59257. }
  59258. /**
  59259. * Looks up the match builder with identification $id and returns it.
  59260. */
  59261. public function lookupMatcher(string $id): ?\PHPUnit\Framework\MockObject\Matcher
  59262. {
  59263. return $this->matcherMap[$id] ?? null;
  59264. }
  59265. /**
  59266. * Registers a matcher with the identification $id. The matcher can later be
  59267. * looked up using lookupMatcher() to figure out if it has been invoked.
  59268. *
  59269. * @throws MatcherAlreadyRegisteredException
  59270. */
  59271. public function registerMatcher(string $id, \PHPUnit\Framework\MockObject\Matcher $matcher): void
  59272. {
  59273. if (isset($this->matcherMap[$id])) {
  59274. throw new \PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException($id);
  59275. }
  59276. $this->matcherMap[$id] = $matcher;
  59277. }
  59278. public function expects(InvocationOrder $rule): InvocationMocker
  59279. {
  59280. $matcher = new \PHPUnit\Framework\MockObject\Matcher($rule);
  59281. $this->addMatcher($matcher);
  59282. return new InvocationMocker($this, $matcher, ...$this->configurableMethods);
  59283. }
  59284. /**
  59285. * @throws \PHPUnit\Framework\MockObject\Exception
  59286. * @throws Exception
  59287. */
  59288. public function invoke(\PHPUnit\Framework\MockObject\Invocation $invocation): mixed
  59289. {
  59290. $exception = null;
  59291. $hasReturnValue = \false;
  59292. $returnValue = null;
  59293. foreach ($this->matchers as $match) {
  59294. try {
  59295. if ($match->matches($invocation)) {
  59296. $value = $match->invoked($invocation);
  59297. if (!$hasReturnValue) {
  59298. $returnValue = $value;
  59299. $hasReturnValue = \true;
  59300. }
  59301. }
  59302. } catch (Exception $e) {
  59303. $exception = $e;
  59304. }
  59305. }
  59306. if ($exception !== null) {
  59307. throw $exception;
  59308. }
  59309. if ($hasReturnValue) {
  59310. return $returnValue;
  59311. }
  59312. if (!$this->returnValueGeneration) {
  59313. if (strtolower($invocation->methodName()) === '__tostring') {
  59314. return '';
  59315. }
  59316. throw new \PHPUnit\Framework\MockObject\ReturnValueNotConfiguredException($invocation);
  59317. }
  59318. return $invocation->generateReturnValue();
  59319. }
  59320. /**
  59321. * @throws Throwable
  59322. */
  59323. public function verify(): void
  59324. {
  59325. foreach ($this->matchers as $matcher) {
  59326. $matcher->verify();
  59327. }
  59328. }
  59329. private function addMatcher(\PHPUnit\Framework\MockObject\Matcher $matcher): void
  59330. {
  59331. $this->matchers[] = $matcher;
  59332. }
  59333. }
  59334. <?php
  59335. declare (strict_types=1);
  59336. /*
  59337. * This file is part of PHPUnit.
  59338. *
  59339. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59340. *
  59341. * For the full copyright and license information, please view the LICENSE
  59342. * file that was distributed with this source code.
  59343. */
  59344. namespace PHPUnit\Framework\MockObject;
  59345. use function sprintf;
  59346. use PHPUnit\Framework\ExpectationFailedException;
  59347. use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
  59348. use PHPUnit\Framework\MockObject\Rule\AnyParameters;
  59349. use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
  59350. use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount;
  59351. use PHPUnit\Framework\MockObject\Rule\InvokedCount;
  59352. use PHPUnit\Framework\MockObject\Rule\MethodName;
  59353. use PHPUnit\Framework\MockObject\Rule\ParametersRule;
  59354. use PHPUnit\Framework\MockObject\Stub\Stub;
  59355. use PHPUnit\Util\ThrowableToStringMapper;
  59356. /**
  59357. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59358. *
  59359. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59360. */
  59361. final class Matcher
  59362. {
  59363. private readonly InvocationOrder $invocationRule;
  59364. private ?string $afterMatchBuilderId = null;
  59365. private ?MethodName $methodNameRule = null;
  59366. private ?ParametersRule $parametersRule = null;
  59367. private ?Stub $stub = null;
  59368. public function __construct(InvocationOrder $rule)
  59369. {
  59370. $this->invocationRule = $rule;
  59371. }
  59372. public function hasMatchers(): bool
  59373. {
  59374. return !$this->invocationRule instanceof AnyInvokedCount;
  59375. }
  59376. public function hasMethodNameRule(): bool
  59377. {
  59378. return $this->methodNameRule !== null;
  59379. }
  59380. public function methodNameRule(): MethodName
  59381. {
  59382. return $this->methodNameRule;
  59383. }
  59384. public function setMethodNameRule(MethodName $rule): void
  59385. {
  59386. $this->methodNameRule = $rule;
  59387. }
  59388. public function hasParametersRule(): bool
  59389. {
  59390. return $this->parametersRule !== null;
  59391. }
  59392. public function setParametersRule(ParametersRule $rule): void
  59393. {
  59394. $this->parametersRule = $rule;
  59395. }
  59396. public function setStub(Stub $stub): void
  59397. {
  59398. $this->stub = $stub;
  59399. }
  59400. public function setAfterMatchBuilderId(string $id): void
  59401. {
  59402. $this->afterMatchBuilderId = $id;
  59403. }
  59404. /**
  59405. * @throws Exception
  59406. * @throws ExpectationFailedException
  59407. * @throws MatchBuilderNotFoundException
  59408. * @throws MethodNameNotConfiguredException
  59409. * @throws RuntimeException
  59410. */
  59411. public function invoked(\PHPUnit\Framework\MockObject\Invocation $invocation): mixed
  59412. {
  59413. if ($this->methodNameRule === null) {
  59414. throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
  59415. }
  59416. if ($this->afterMatchBuilderId !== null) {
  59417. $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId);
  59418. if (!$matcher) {
  59419. throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId);
  59420. }
  59421. }
  59422. $this->invocationRule->invoked($invocation);
  59423. try {
  59424. $this->parametersRule?->apply($invocation);
  59425. } catch (ExpectationFailedException $e) {
  59426. throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure());
  59427. }
  59428. if ($this->stub) {
  59429. return $this->stub->invoke($invocation);
  59430. }
  59431. return $invocation->generateReturnValue();
  59432. }
  59433. /**
  59434. * @throws ExpectationFailedException
  59435. * @throws MatchBuilderNotFoundException
  59436. * @throws MethodNameNotConfiguredException
  59437. * @throws RuntimeException
  59438. */
  59439. public function matches(\PHPUnit\Framework\MockObject\Invocation $invocation): bool
  59440. {
  59441. if ($this->afterMatchBuilderId !== null) {
  59442. $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId);
  59443. if (!$matcher) {
  59444. throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId);
  59445. }
  59446. if (!$matcher->invocationRule->hasBeenInvoked()) {
  59447. return \false;
  59448. }
  59449. }
  59450. if ($this->methodNameRule === null) {
  59451. throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
  59452. }
  59453. if (!$this->invocationRule->matches($invocation)) {
  59454. return \false;
  59455. }
  59456. try {
  59457. if (!$this->methodNameRule->matches($invocation)) {
  59458. return \false;
  59459. }
  59460. } catch (ExpectationFailedException $e) {
  59461. throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure());
  59462. }
  59463. return \true;
  59464. }
  59465. /**
  59466. * @throws ExpectationFailedException
  59467. * @throws MethodNameNotConfiguredException
  59468. */
  59469. public function verify(): void
  59470. {
  59471. if ($this->methodNameRule === null) {
  59472. throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
  59473. }
  59474. try {
  59475. $this->invocationRule->verify();
  59476. if ($this->parametersRule === null) {
  59477. $this->parametersRule = new AnyParameters();
  59478. }
  59479. $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount;
  59480. $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever();
  59481. $invocationIsAtMost = $this->invocationRule instanceof InvokedAtMostCount;
  59482. if (!$invocationIsAny && !$invocationIsNever && !$invocationIsAtMost) {
  59483. $this->parametersRule->verify();
  59484. }
  59485. } catch (ExpectationFailedException $e) {
  59486. throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s.\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), ThrowableToStringMapper::map($e)));
  59487. }
  59488. }
  59489. }
  59490. <?php
  59491. declare (strict_types=1);
  59492. /*
  59493. * This file is part of PHPUnit.
  59494. *
  59495. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59496. *
  59497. * For the full copyright and license information, please view the LICENSE
  59498. * file that was distributed with this source code.
  59499. */
  59500. namespace PHPUnit\Framework\MockObject;
  59501. use function sprintf;
  59502. use function strtolower;
  59503. use PHPUnit\Framework\Constraint\Constraint;
  59504. /**
  59505. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59506. *
  59507. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59508. */
  59509. final class MethodNameConstraint extends Constraint
  59510. {
  59511. private readonly string $methodName;
  59512. public function __construct(string $methodName)
  59513. {
  59514. $this->methodName = $methodName;
  59515. }
  59516. public function toString(): string
  59517. {
  59518. return sprintf('is "%s"', $this->methodName);
  59519. }
  59520. protected function matches(mixed $other): bool
  59521. {
  59522. return strtolower($this->methodName) === strtolower((string) $other);
  59523. }
  59524. }
  59525. <?php
  59526. declare (strict_types=1);
  59527. /*
  59528. * This file is part of PHPUnit.
  59529. *
  59530. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59531. *
  59532. * For the full copyright and license information, please view the LICENSE
  59533. * file that was distributed with this source code.
  59534. */
  59535. namespace PHPUnit\Framework\MockObject;
  59536. use function array_keys;
  59537. use function array_map;
  59538. use function explode;
  59539. use function in_array;
  59540. use function interface_exists;
  59541. use function sprintf;
  59542. use function str_contains;
  59543. use function str_ends_with;
  59544. use function str_starts_with;
  59545. use function substr;
  59546. use PHPUnit\Framework\MockObject\Generator\Generator;
  59547. use ReflectionClass;
  59548. use stdClass;
  59549. use Throwable;
  59550. /**
  59551. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59552. *
  59553. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59554. */
  59555. final class ReturnValueGenerator
  59556. {
  59557. /**
  59558. * @psalm-param class-string $className
  59559. * @psalm-param non-empty-string $methodName
  59560. * @psalm-param class-string $stubClassName
  59561. *
  59562. * @throws Exception
  59563. */
  59564. public function generate(string $className, string $methodName, string $stubClassName, string $returnType): mixed
  59565. {
  59566. $intersection = \false;
  59567. $union = \false;
  59568. if (str_contains($returnType, '|')) {
  59569. $types = explode('|', $returnType);
  59570. $union = \true;
  59571. foreach (array_keys($types) as $key) {
  59572. if (str_starts_with($types[$key], '(') && str_ends_with($types[$key], ')')) {
  59573. $types[$key] = substr($types[$key], 1, -1);
  59574. }
  59575. }
  59576. } elseif (str_contains($returnType, '&')) {
  59577. $types = explode('&', $returnType);
  59578. $intersection = \true;
  59579. } else {
  59580. $types = [$returnType];
  59581. }
  59582. if (!$intersection) {
  59583. $lowerTypes = array_map('strtolower', $types);
  59584. if (in_array('', $lowerTypes, \true) || in_array('null', $lowerTypes, \true) || in_array('mixed', $lowerTypes, \true) || in_array('void', $lowerTypes, \true)) {
  59585. return null;
  59586. }
  59587. if (in_array('true', $lowerTypes, \true)) {
  59588. return \true;
  59589. }
  59590. if (in_array('false', $lowerTypes, \true) || in_array('bool', $lowerTypes, \true)) {
  59591. return \false;
  59592. }
  59593. if (in_array('float', $lowerTypes, \true)) {
  59594. return 0.0;
  59595. }
  59596. if (in_array('int', $lowerTypes, \true)) {
  59597. return 0;
  59598. }
  59599. if (in_array('string', $lowerTypes, \true)) {
  59600. return '';
  59601. }
  59602. if (in_array('array', $lowerTypes, \true)) {
  59603. return [];
  59604. }
  59605. if (in_array('static', $lowerTypes, \true)) {
  59606. return $this->newInstanceOf($stubClassName, $className, $methodName);
  59607. }
  59608. if (in_array('object', $lowerTypes, \true)) {
  59609. return new stdClass();
  59610. }
  59611. if (in_array('callable', $lowerTypes, \true) || in_array('closure', $lowerTypes, \true)) {
  59612. return static function (): void {
  59613. };
  59614. }
  59615. if (in_array('traversable', $lowerTypes, \true) || in_array('generator', $lowerTypes, \true) || in_array('iterable', $lowerTypes, \true)) {
  59616. $generator = static function (): \Generator {
  59617. yield from [];
  59618. };
  59619. return $generator();
  59620. }
  59621. if (!$union) {
  59622. return $this->testDoubleFor($returnType, $className, $methodName);
  59623. }
  59624. }
  59625. if ($union) {
  59626. foreach ($types as $type) {
  59627. if (str_contains($type, '&')) {
  59628. $_types = explode('&', $type);
  59629. if ($this->onlyInterfaces($_types)) {
  59630. return $this->testDoubleForIntersectionOfInterfaces($_types, $className, $methodName);
  59631. }
  59632. }
  59633. }
  59634. }
  59635. if ($intersection && $this->onlyInterfaces($types)) {
  59636. return $this->testDoubleForIntersectionOfInterfaces($types, $className, $methodName);
  59637. }
  59638. $reason = '';
  59639. if ($union) {
  59640. $reason = ' because the declared return type is a union';
  59641. } elseif ($intersection) {
  59642. $reason = ' because the declared return type is an intersection';
  59643. }
  59644. throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated%s, please configure a return value for this method', $className, $methodName, $reason));
  59645. }
  59646. /**
  59647. * @psalm-param non-empty-list<string> $types
  59648. */
  59649. private function onlyInterfaces(array $types): bool
  59650. {
  59651. foreach ($types as $type) {
  59652. if (!interface_exists($type)) {
  59653. return \false;
  59654. }
  59655. }
  59656. return \true;
  59657. }
  59658. /**
  59659. * @psalm-param class-string $stubClassName
  59660. * @psalm-param class-string $className
  59661. * @psalm-param non-empty-string $methodName
  59662. *
  59663. * @throws RuntimeException
  59664. */
  59665. private function newInstanceOf(string $stubClassName, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
  59666. {
  59667. try {
  59668. return (new ReflectionClass($stubClassName))->newInstanceWithoutConstructor();
  59669. // @codeCoverageIgnoreStart
  59670. } catch (Throwable $t) {
  59671. throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
  59672. // @codeCoverageIgnoreEnd
  59673. }
  59674. }
  59675. /**
  59676. * @psalm-param class-string $type
  59677. * @psalm-param class-string $className
  59678. * @psalm-param non-empty-string $methodName
  59679. *
  59680. * @throws RuntimeException
  59681. */
  59682. private function testDoubleFor(string $type, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
  59683. {
  59684. try {
  59685. return (new Generator())->testDouble($type, \false, [], [], '', \false);
  59686. // @codeCoverageIgnoreStart
  59687. } catch (Throwable $t) {
  59688. throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
  59689. // @codeCoverageIgnoreEnd
  59690. }
  59691. }
  59692. /**
  59693. * @psalm-param non-empty-list<string> $types
  59694. * @psalm-param class-string $className
  59695. * @psalm-param non-empty-string $methodName
  59696. *
  59697. * @throws RuntimeException
  59698. */
  59699. private function testDoubleForIntersectionOfInterfaces(array $types, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
  59700. {
  59701. try {
  59702. return (new Generator())->testDoubleForInterfaceIntersection($types, \false);
  59703. // @codeCoverageIgnoreStart
  59704. } catch (Throwable $t) {
  59705. throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
  59706. // @codeCoverageIgnoreEnd
  59707. }
  59708. }
  59709. }
  59710. <?php
  59711. declare (strict_types=1);
  59712. /*
  59713. * This file is part of PHPUnit.
  59714. *
  59715. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59716. *
  59717. * For the full copyright and license information, please view the LICENSE
  59718. * file that was distributed with this source code.
  59719. */
  59720. namespace PHPUnit\Framework\MockObject\Rule;
  59721. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59722. /**
  59723. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59724. *
  59725. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59726. */
  59727. final class AnyInvokedCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
  59728. {
  59729. public function toString(): string
  59730. {
  59731. return 'invoked zero or more times';
  59732. }
  59733. public function verify(): void
  59734. {
  59735. }
  59736. public function matches(BaseInvocation $invocation): bool
  59737. {
  59738. return \true;
  59739. }
  59740. }
  59741. <?php
  59742. declare (strict_types=1);
  59743. /*
  59744. * This file is part of PHPUnit.
  59745. *
  59746. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59747. *
  59748. * For the full copyright and license information, please view the LICENSE
  59749. * file that was distributed with this source code.
  59750. */
  59751. namespace PHPUnit\Framework\MockObject\Rule;
  59752. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59753. /**
  59754. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59755. *
  59756. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59757. */
  59758. final class AnyParameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule
  59759. {
  59760. public function apply(BaseInvocation $invocation): void
  59761. {
  59762. }
  59763. public function verify(): void
  59764. {
  59765. }
  59766. }
  59767. <?php
  59768. declare (strict_types=1);
  59769. /*
  59770. * This file is part of PHPUnit.
  59771. *
  59772. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59773. *
  59774. * For the full copyright and license information, please view the LICENSE
  59775. * file that was distributed with this source code.
  59776. */
  59777. namespace PHPUnit\Framework\MockObject\Rule;
  59778. use function count;
  59779. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59780. use PHPUnit\Framework\SelfDescribing;
  59781. /**
  59782. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59783. *
  59784. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59785. */
  59786. abstract class InvocationOrder implements SelfDescribing
  59787. {
  59788. /**
  59789. * @psalm-var list<BaseInvocation>
  59790. */
  59791. private array $invocations = [];
  59792. public function numberOfInvocations(): int
  59793. {
  59794. return count($this->invocations);
  59795. }
  59796. public function hasBeenInvoked(): bool
  59797. {
  59798. return count($this->invocations) > 0;
  59799. }
  59800. final public function invoked(BaseInvocation $invocation): void
  59801. {
  59802. $this->invocations[] = $invocation;
  59803. $this->invokedDo($invocation);
  59804. }
  59805. abstract public function matches(BaseInvocation $invocation): bool;
  59806. abstract public function verify(): void;
  59807. protected function invokedDo(BaseInvocation $invocation): void
  59808. {
  59809. }
  59810. }
  59811. <?php
  59812. declare (strict_types=1);
  59813. /*
  59814. * This file is part of PHPUnit.
  59815. *
  59816. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59817. *
  59818. * For the full copyright and license information, please view the LICENSE
  59819. * file that was distributed with this source code.
  59820. */
  59821. namespace PHPUnit\Framework\MockObject\Rule;
  59822. use function sprintf;
  59823. use PHPUnit\Framework\ExpectationFailedException;
  59824. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59825. /**
  59826. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59827. *
  59828. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59829. */
  59830. final class InvokedAtLeastCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
  59831. {
  59832. private readonly int $requiredInvocations;
  59833. public function __construct(int $requiredInvocations)
  59834. {
  59835. $this->requiredInvocations = $requiredInvocations;
  59836. }
  59837. public function toString(): string
  59838. {
  59839. return sprintf('invoked at least %d time%s', $this->requiredInvocations, $this->requiredInvocations !== 1 ? 's' : '');
  59840. }
  59841. /**
  59842. * Verifies that the current expectation is valid. If everything is OK the
  59843. * code should just return, if not it must throw an exception.
  59844. *
  59845. * @throws ExpectationFailedException
  59846. */
  59847. public function verify(): void
  59848. {
  59849. $actualInvocations = $this->numberOfInvocations();
  59850. if ($actualInvocations < $this->requiredInvocations) {
  59851. throw new ExpectationFailedException(sprintf('Expected invocation at least %d time%s but it occurred %d time%s.', $this->requiredInvocations, $this->requiredInvocations !== 1 ? 's' : '', $actualInvocations, $actualInvocations !== 1 ? 's' : ''));
  59852. }
  59853. }
  59854. public function matches(BaseInvocation $invocation): bool
  59855. {
  59856. return \true;
  59857. }
  59858. }
  59859. <?php
  59860. declare (strict_types=1);
  59861. /*
  59862. * This file is part of PHPUnit.
  59863. *
  59864. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59865. *
  59866. * For the full copyright and license information, please view the LICENSE
  59867. * file that was distributed with this source code.
  59868. */
  59869. namespace PHPUnit\Framework\MockObject\Rule;
  59870. use PHPUnit\Framework\ExpectationFailedException;
  59871. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59872. /**
  59873. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59874. *
  59875. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59876. */
  59877. final class InvokedAtLeastOnce extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
  59878. {
  59879. public function toString(): string
  59880. {
  59881. return 'invoked at least once';
  59882. }
  59883. /**
  59884. * Verifies that the current expectation is valid. If everything is OK the
  59885. * code should just return, if not it must throw an exception.
  59886. *
  59887. * @throws ExpectationFailedException
  59888. */
  59889. public function verify(): void
  59890. {
  59891. $count = $this->numberOfInvocations();
  59892. if ($count < 1) {
  59893. throw new ExpectationFailedException('Expected invocation at least once but it never occurred.');
  59894. }
  59895. }
  59896. public function matches(BaseInvocation $invocation): bool
  59897. {
  59898. return \true;
  59899. }
  59900. }
  59901. <?php
  59902. declare (strict_types=1);
  59903. /*
  59904. * This file is part of PHPUnit.
  59905. *
  59906. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59907. *
  59908. * For the full copyright and license information, please view the LICENSE
  59909. * file that was distributed with this source code.
  59910. */
  59911. namespace PHPUnit\Framework\MockObject\Rule;
  59912. use function sprintf;
  59913. use PHPUnit\Framework\ExpectationFailedException;
  59914. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59915. /**
  59916. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59917. *
  59918. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59919. */
  59920. final class InvokedAtMostCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
  59921. {
  59922. private readonly int $allowedInvocations;
  59923. public function __construct(int $allowedInvocations)
  59924. {
  59925. $this->allowedInvocations = $allowedInvocations;
  59926. }
  59927. public function toString(): string
  59928. {
  59929. return sprintf('invoked at most %d time%s', $this->allowedInvocations, $this->allowedInvocations !== 1 ? 's' : '');
  59930. }
  59931. /**
  59932. * Verifies that the current expectation is valid. If everything is OK the
  59933. * code should just return, if not it must throw an exception.
  59934. *
  59935. * @throws ExpectationFailedException
  59936. */
  59937. public function verify(): void
  59938. {
  59939. $actualInvocations = $this->numberOfInvocations();
  59940. if ($actualInvocations > $this->allowedInvocations) {
  59941. throw new ExpectationFailedException(sprintf('Expected invocation at most %d time%s but it occurred %d time%s.', $this->allowedInvocations, $this->allowedInvocations !== 1 ? 's' : '', $actualInvocations, $actualInvocations !== 1 ? 's' : ''));
  59942. }
  59943. }
  59944. public function matches(BaseInvocation $invocation): bool
  59945. {
  59946. return \true;
  59947. }
  59948. }
  59949. <?php
  59950. declare (strict_types=1);
  59951. /*
  59952. * This file is part of PHPUnit.
  59953. *
  59954. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59955. *
  59956. * For the full copyright and license information, please view the LICENSE
  59957. * file that was distributed with this source code.
  59958. */
  59959. namespace PHPUnit\Framework\MockObject\Rule;
  59960. use function sprintf;
  59961. use PHPUnit\Framework\ExpectationFailedException;
  59962. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  59963. /**
  59964. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  59965. *
  59966. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  59967. */
  59968. final class InvokedCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
  59969. {
  59970. private readonly int $expectedCount;
  59971. public function __construct(int $expectedCount)
  59972. {
  59973. $this->expectedCount = $expectedCount;
  59974. }
  59975. public function isNever(): bool
  59976. {
  59977. return $this->expectedCount === 0;
  59978. }
  59979. public function toString(): string
  59980. {
  59981. return sprintf('invoked %d time%s', $this->expectedCount, $this->expectedCount !== 1 ? 's' : '');
  59982. }
  59983. public function matches(BaseInvocation $invocation): bool
  59984. {
  59985. return \true;
  59986. }
  59987. /**
  59988. * Verifies that the current expectation is valid. If everything is OK the
  59989. * code should just return, if not it must throw an exception.
  59990. *
  59991. * @throws ExpectationFailedException
  59992. */
  59993. public function verify(): void
  59994. {
  59995. $actualCount = $this->numberOfInvocations();
  59996. if ($actualCount !== $this->expectedCount) {
  59997. throw new ExpectationFailedException(sprintf('Method was expected to be called %d time%s, actually called %d time%s.', $this->expectedCount, $this->expectedCount !== 1 ? 's' : '', $actualCount, $actualCount !== 1 ? 's' : ''));
  59998. }
  59999. }
  60000. /**
  60001. * @throws ExpectationFailedException
  60002. */
  60003. protected function invokedDo(BaseInvocation $invocation): void
  60004. {
  60005. $count = $this->numberOfInvocations();
  60006. if ($count > $this->expectedCount) {
  60007. $message = $invocation->toString() . ' ';
  60008. $message .= match ($this->expectedCount) {
  60009. 0 => 'was not expected to be called.',
  60010. 1 => 'was not expected to be called more than once.',
  60011. default => sprintf('was not expected to be called more than %d times.', $this->expectedCount),
  60012. };
  60013. throw new ExpectationFailedException($message);
  60014. }
  60015. }
  60016. }
  60017. <?php
  60018. declare (strict_types=1);
  60019. /*
  60020. * This file is part of PHPUnit.
  60021. *
  60022. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60023. *
  60024. * For the full copyright and license information, please view the LICENSE
  60025. * file that was distributed with this source code.
  60026. */
  60027. namespace PHPUnit\Framework\MockObject\Rule;
  60028. use function is_string;
  60029. use PHPUnit\Framework\Constraint\Constraint;
  60030. use PHPUnit\Framework\ExpectationFailedException;
  60031. use PHPUnit\Framework\InvalidArgumentException;
  60032. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  60033. use PHPUnit\Framework\MockObject\MethodNameConstraint;
  60034. /**
  60035. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60036. *
  60037. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60038. */
  60039. final class MethodName
  60040. {
  60041. private readonly Constraint $constraint;
  60042. /**
  60043. * @throws InvalidArgumentException
  60044. */
  60045. public function __construct(Constraint|string $constraint)
  60046. {
  60047. if (is_string($constraint)) {
  60048. $constraint = new MethodNameConstraint($constraint);
  60049. }
  60050. $this->constraint = $constraint;
  60051. }
  60052. public function toString(): string
  60053. {
  60054. return 'method name ' . $this->constraint->toString();
  60055. }
  60056. /**
  60057. * @throws ExpectationFailedException
  60058. */
  60059. public function matches(BaseInvocation $invocation): bool
  60060. {
  60061. return $this->matchesName($invocation->methodName());
  60062. }
  60063. /**
  60064. * @throws ExpectationFailedException
  60065. */
  60066. public function matchesName(string $methodName): bool
  60067. {
  60068. return (bool) $this->constraint->evaluate($methodName, '', \true);
  60069. }
  60070. }
  60071. <?php
  60072. declare (strict_types=1);
  60073. /*
  60074. * This file is part of PHPUnit.
  60075. *
  60076. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60077. *
  60078. * For the full copyright and license information, please view the LICENSE
  60079. * file that was distributed with this source code.
  60080. */
  60081. namespace PHPUnit\Framework\MockObject\Rule;
  60082. use function count;
  60083. use function sprintf;
  60084. use Exception;
  60085. use PHPUnit\Framework\Constraint\Callback;
  60086. use PHPUnit\Framework\Constraint\Constraint;
  60087. use PHPUnit\Framework\Constraint\IsAnything;
  60088. use PHPUnit\Framework\Constraint\IsEqual;
  60089. use PHPUnit\Framework\ExpectationFailedException;
  60090. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  60091. /**
  60092. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60093. *
  60094. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60095. */
  60096. final class Parameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule
  60097. {
  60098. /**
  60099. * @psalm-var list<Constraint>
  60100. */
  60101. private array $parameters = [];
  60102. private ?BaseInvocation $invocation = null;
  60103. private null|bool|ExpectationFailedException $parameterVerificationResult;
  60104. /**
  60105. * @throws \PHPUnit\Framework\Exception
  60106. */
  60107. public function __construct(array $parameters)
  60108. {
  60109. foreach ($parameters as $parameter) {
  60110. if (!$parameter instanceof Constraint) {
  60111. $parameter = new IsEqual($parameter);
  60112. }
  60113. $this->parameters[] = $parameter;
  60114. }
  60115. }
  60116. /**
  60117. * @throws Exception
  60118. */
  60119. public function apply(BaseInvocation $invocation): void
  60120. {
  60121. $this->invocation = $invocation;
  60122. $this->parameterVerificationResult = null;
  60123. try {
  60124. $this->parameterVerificationResult = $this->doVerify();
  60125. } catch (ExpectationFailedException $e) {
  60126. $this->parameterVerificationResult = $e;
  60127. throw $this->parameterVerificationResult;
  60128. }
  60129. }
  60130. /**
  60131. * Checks if the invocation $invocation matches the current rules. If it
  60132. * does the rule will get the invoked() method called which should check
  60133. * if an expectation is met.
  60134. *
  60135. * @throws ExpectationFailedException
  60136. */
  60137. public function verify(): void
  60138. {
  60139. $this->doVerify();
  60140. }
  60141. /**
  60142. * @throws ExpectationFailedException
  60143. */
  60144. private function doVerify(): bool
  60145. {
  60146. if (isset($this->parameterVerificationResult)) {
  60147. return $this->guardAgainstDuplicateEvaluationOfParameterConstraints();
  60148. }
  60149. if ($this->invocation === null) {
  60150. throw new ExpectationFailedException('Doubled method does not exist.');
  60151. }
  60152. if (count($this->invocation->parameters()) < count($this->parameters)) {
  60153. $message = 'Parameter count for invocation %s is too low.';
  60154. // The user called `->with($this->anything())`, but may have meant
  60155. // `->withAnyParameters()`.
  60156. //
  60157. // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
  60158. if (count($this->parameters) === 1 && $this->parameters[0]::class === IsAnything::class) {
  60159. $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
  60160. }
  60161. throw new ExpectationFailedException(sprintf($message, $this->invocation->toString()));
  60162. }
  60163. foreach ($this->parameters as $i => $parameter) {
  60164. if ($parameter instanceof Callback && $parameter->isVariadic()) {
  60165. $other = $this->invocation->parameters();
  60166. } else {
  60167. $other = $this->invocation->parameters()[$i];
  60168. }
  60169. $parameter->evaluate($other, sprintf('Parameter %s for invocation %s does not match expected value.', $i, $this->invocation->toString()));
  60170. }
  60171. return \true;
  60172. }
  60173. /**
  60174. * @throws ExpectationFailedException
  60175. */
  60176. private function guardAgainstDuplicateEvaluationOfParameterConstraints(): bool
  60177. {
  60178. if ($this->parameterVerificationResult instanceof ExpectationFailedException) {
  60179. throw $this->parameterVerificationResult;
  60180. }
  60181. return (bool) $this->parameterVerificationResult;
  60182. }
  60183. }
  60184. <?php
  60185. declare (strict_types=1);
  60186. /*
  60187. * This file is part of PHPUnit.
  60188. *
  60189. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60190. *
  60191. * For the full copyright and license information, please view the LICENSE
  60192. * file that was distributed with this source code.
  60193. */
  60194. namespace PHPUnit\Framework\MockObject\Rule;
  60195. use PHPUnit\Framework\ExpectationFailedException;
  60196. use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
  60197. /**
  60198. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60199. */
  60200. interface ParametersRule
  60201. {
  60202. /**
  60203. * @throws ExpectationFailedException if the invocation violates the rule
  60204. */
  60205. public function apply(BaseInvocation $invocation): void;
  60206. public function verify(): void;
  60207. }
  60208. <?php
  60209. declare (strict_types=1);
  60210. /*
  60211. * This file is part of PHPUnit.
  60212. *
  60213. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60214. *
  60215. * For the full copyright and license information, please view the LICENSE
  60216. * file that was distributed with this source code.
  60217. */
  60218. namespace PHPUnit\Framework\MockObject\Stub;
  60219. use function array_shift;
  60220. use function count;
  60221. use PHPUnit\Framework\MockObject\Invocation;
  60222. use PHPUnit\Framework\MockObject\NoMoreReturnValuesConfiguredException;
  60223. /**
  60224. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60225. *
  60226. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60227. */
  60228. final class ConsecutiveCalls implements \PHPUnit\Framework\MockObject\Stub\Stub
  60229. {
  60230. private array $stack;
  60231. private int $numberOfConfiguredReturnValues;
  60232. public function __construct(array $stack)
  60233. {
  60234. $this->stack = $stack;
  60235. $this->numberOfConfiguredReturnValues = count($stack);
  60236. }
  60237. /**
  60238. * @throws NoMoreReturnValuesConfiguredException
  60239. */
  60240. public function invoke(Invocation $invocation): mixed
  60241. {
  60242. if (empty($this->stack)) {
  60243. throw new NoMoreReturnValuesConfiguredException($invocation, $this->numberOfConfiguredReturnValues);
  60244. }
  60245. $value = array_shift($this->stack);
  60246. if ($value instanceof \PHPUnit\Framework\MockObject\Stub\Stub) {
  60247. $value = $value->invoke($invocation);
  60248. }
  60249. return $value;
  60250. }
  60251. }
  60252. <?php
  60253. declare (strict_types=1);
  60254. /*
  60255. * This file is part of PHPUnit.
  60256. *
  60257. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60258. *
  60259. * For the full copyright and license information, please view the LICENSE
  60260. * file that was distributed with this source code.
  60261. */
  60262. namespace PHPUnit\Framework\MockObject\Stub;
  60263. use PHPUnit\Framework\MockObject\Invocation;
  60264. use Throwable;
  60265. /**
  60266. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60267. *
  60268. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60269. */
  60270. final class Exception implements \PHPUnit\Framework\MockObject\Stub\Stub
  60271. {
  60272. private readonly Throwable $exception;
  60273. public function __construct(Throwable $exception)
  60274. {
  60275. $this->exception = $exception;
  60276. }
  60277. /**
  60278. * @throws Throwable
  60279. */
  60280. public function invoke(Invocation $invocation): never
  60281. {
  60282. throw $this->exception;
  60283. }
  60284. }
  60285. <?php
  60286. declare (strict_types=1);
  60287. /*
  60288. * This file is part of PHPUnit.
  60289. *
  60290. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60291. *
  60292. * For the full copyright and license information, please view the LICENSE
  60293. * file that was distributed with this source code.
  60294. */
  60295. namespace PHPUnit\Framework\MockObject\Stub;
  60296. use PHPUnit\Framework\MockObject\Invocation;
  60297. /**
  60298. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60299. *
  60300. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60301. */
  60302. final class ReturnArgument implements \PHPUnit\Framework\MockObject\Stub\Stub
  60303. {
  60304. private readonly int $argumentIndex;
  60305. public function __construct(int $argumentIndex)
  60306. {
  60307. $this->argumentIndex = $argumentIndex;
  60308. }
  60309. public function invoke(Invocation $invocation): mixed
  60310. {
  60311. return $invocation->parameters()[$this->argumentIndex] ?? null;
  60312. }
  60313. }
  60314. <?php
  60315. declare (strict_types=1);
  60316. /*
  60317. * This file is part of PHPUnit.
  60318. *
  60319. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60320. *
  60321. * For the full copyright and license information, please view the LICENSE
  60322. * file that was distributed with this source code.
  60323. */
  60324. namespace PHPUnit\Framework\MockObject\Stub;
  60325. use function call_user_func_array;
  60326. use PHPUnit\Framework\MockObject\Invocation;
  60327. /**
  60328. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60329. *
  60330. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60331. */
  60332. final class ReturnCallback implements \PHPUnit\Framework\MockObject\Stub\Stub
  60333. {
  60334. /**
  60335. * @var callable
  60336. */
  60337. private $callback;
  60338. public function __construct(callable $callback)
  60339. {
  60340. $this->callback = $callback;
  60341. }
  60342. public function invoke(Invocation $invocation): mixed
  60343. {
  60344. return call_user_func_array($this->callback, $invocation->parameters());
  60345. }
  60346. }
  60347. <?php
  60348. declare (strict_types=1);
  60349. /*
  60350. * This file is part of PHPUnit.
  60351. *
  60352. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60353. *
  60354. * For the full copyright and license information, please view the LICENSE
  60355. * file that was distributed with this source code.
  60356. */
  60357. namespace PHPUnit\Framework\MockObject\Stub;
  60358. use PHPUnit\Framework\MockObject\Invocation;
  60359. /**
  60360. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60361. *
  60362. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60363. */
  60364. final class ReturnReference implements \PHPUnit\Framework\MockObject\Stub\Stub
  60365. {
  60366. private mixed $reference;
  60367. public function __construct(mixed &$reference)
  60368. {
  60369. $this->reference =& $reference;
  60370. }
  60371. public function invoke(Invocation $invocation): mixed
  60372. {
  60373. return $this->reference;
  60374. }
  60375. }
  60376. <?php
  60377. declare (strict_types=1);
  60378. /*
  60379. * This file is part of PHPUnit.
  60380. *
  60381. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60382. *
  60383. * For the full copyright and license information, please view the LICENSE
  60384. * file that was distributed with this source code.
  60385. */
  60386. namespace PHPUnit\Framework\MockObject\Stub;
  60387. use PHPUnit\Framework\MockObject\Invocation;
  60388. use PHPUnit\Framework\MockObject\RuntimeException;
  60389. /**
  60390. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60391. *
  60392. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60393. */
  60394. final class ReturnSelf implements \PHPUnit\Framework\MockObject\Stub\Stub
  60395. {
  60396. /**
  60397. * @throws RuntimeException
  60398. */
  60399. public function invoke(Invocation $invocation): object
  60400. {
  60401. return $invocation->object();
  60402. }
  60403. }
  60404. <?php
  60405. declare (strict_types=1);
  60406. /*
  60407. * This file is part of PHPUnit.
  60408. *
  60409. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60410. *
  60411. * For the full copyright and license information, please view the LICENSE
  60412. * file that was distributed with this source code.
  60413. */
  60414. namespace PHPUnit\Framework\MockObject\Stub;
  60415. use PHPUnit\Framework\MockObject\Invocation;
  60416. /**
  60417. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60418. *
  60419. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60420. */
  60421. final class ReturnStub implements \PHPUnit\Framework\MockObject\Stub\Stub
  60422. {
  60423. private readonly mixed $value;
  60424. public function __construct(mixed $value)
  60425. {
  60426. $this->value = $value;
  60427. }
  60428. public function invoke(Invocation $invocation): mixed
  60429. {
  60430. return $this->value;
  60431. }
  60432. }
  60433. <?php
  60434. declare (strict_types=1);
  60435. /*
  60436. * This file is part of PHPUnit.
  60437. *
  60438. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60439. *
  60440. * For the full copyright and license information, please view the LICENSE
  60441. * file that was distributed with this source code.
  60442. */
  60443. namespace PHPUnit\Framework\MockObject\Stub;
  60444. use function array_pop;
  60445. use function count;
  60446. use function is_array;
  60447. use PHPUnit\Framework\MockObject\Invocation;
  60448. /**
  60449. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60450. *
  60451. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60452. */
  60453. final class ReturnValueMap implements \PHPUnit\Framework\MockObject\Stub\Stub
  60454. {
  60455. private readonly array $valueMap;
  60456. public function __construct(array $valueMap)
  60457. {
  60458. $this->valueMap = $valueMap;
  60459. }
  60460. public function invoke(Invocation $invocation): mixed
  60461. {
  60462. $parameterCount = count($invocation->parameters());
  60463. foreach ($this->valueMap as $map) {
  60464. if (!is_array($map) || $parameterCount !== count($map) - 1) {
  60465. continue;
  60466. }
  60467. $return = array_pop($map);
  60468. if ($invocation->parameters() === $map) {
  60469. return $return;
  60470. }
  60471. }
  60472. return null;
  60473. }
  60474. }
  60475. <?php
  60476. declare (strict_types=1);
  60477. /*
  60478. * This file is part of PHPUnit.
  60479. *
  60480. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60481. *
  60482. * For the full copyright and license information, please view the LICENSE
  60483. * file that was distributed with this source code.
  60484. */
  60485. namespace PHPUnit\Framework\MockObject\Stub;
  60486. use PHPUnit\Framework\MockObject\Invocation;
  60487. /**
  60488. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60489. *
  60490. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60491. */
  60492. interface Stub
  60493. {
  60494. /**
  60495. * Fakes the processing of the invocation $invocation by returning a
  60496. * specific value.
  60497. */
  60498. public function invoke(Invocation $invocation): mixed;
  60499. }
  60500. <?php
  60501. declare (strict_types=1);
  60502. /*
  60503. * This file is part of PHPUnit.
  60504. *
  60505. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60506. *
  60507. * For the full copyright and license information, please view the LICENSE
  60508. * file that was distributed with this source code.
  60509. */
  60510. namespace PHPUnit\Framework;
  60511. /**
  60512. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60513. *
  60514. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60515. */
  60516. interface Reorderable
  60517. {
  60518. public function sortId(): string;
  60519. /**
  60520. * @psalm-return list<ExecutionOrderDependency>
  60521. */
  60522. public function provides(): array;
  60523. /**
  60524. * @psalm-return list<ExecutionOrderDependency>
  60525. */
  60526. public function requires(): array;
  60527. }
  60528. <?php
  60529. declare (strict_types=1);
  60530. /*
  60531. * This file is part of PHPUnit.
  60532. *
  60533. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60534. *
  60535. * For the full copyright and license information, please view the LICENSE
  60536. * file that was distributed with this source code.
  60537. */
  60538. namespace PHPUnit\Framework;
  60539. /**
  60540. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60541. *
  60542. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60543. */
  60544. interface SelfDescribing
  60545. {
  60546. /**
  60547. * Returns a string representation of the object.
  60548. */
  60549. public function toString(): string;
  60550. }
  60551. <?php
  60552. declare (strict_types=1);
  60553. /*
  60554. * This file is part of PHPUnit.
  60555. *
  60556. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60557. *
  60558. * For the full copyright and license information, please view the LICENSE
  60559. * file that was distributed with this source code.
  60560. */
  60561. namespace PHPUnit\Framework;
  60562. use Countable;
  60563. /**
  60564. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60565. */
  60566. interface Test extends Countable
  60567. {
  60568. public function run(): void;
  60569. }
  60570. <?php
  60571. declare (strict_types=1);
  60572. /*
  60573. * This file is part of PHPUnit.
  60574. *
  60575. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60576. *
  60577. * For the full copyright and license information, please view the LICENSE
  60578. * file that was distributed with this source code.
  60579. */
  60580. namespace PHPUnit\Framework;
  60581. use function assert;
  60582. use PHPUnit\Metadata\Api\DataProvider;
  60583. use PHPUnit\Metadata\Api\Groups;
  60584. use PHPUnit\Metadata\Api\Requirements;
  60585. use PHPUnit\Metadata\BackupGlobals;
  60586. use PHPUnit\Metadata\BackupStaticProperties;
  60587. use PHPUnit\Metadata\ExcludeGlobalVariableFromBackup;
  60588. use PHPUnit\Metadata\ExcludeStaticPropertyFromBackup;
  60589. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  60590. use PHPUnit\Metadata\PreserveGlobalState;
  60591. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  60592. use ReflectionClass;
  60593. /**
  60594. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60595. *
  60596. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  60597. */
  60598. final class TestBuilder
  60599. {
  60600. /**
  60601. * @psalm-param non-empty-string $methodName
  60602. *
  60603. * @throws InvalidDataProviderException
  60604. */
  60605. public function build(ReflectionClass $theClass, string $methodName): \PHPUnit\Framework\Test
  60606. {
  60607. $className = $theClass->getName();
  60608. $data = null;
  60609. if ($this->requirementsSatisfied($className, $methodName)) {
  60610. $data = (new DataProvider())->providedData($className, $methodName);
  60611. }
  60612. if ($data !== null) {
  60613. return $this->buildDataProviderTestSuite($methodName, $className, $data, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName));
  60614. }
  60615. $test = new $className($methodName);
  60616. assert($test instanceof \PHPUnit\Framework\TestCase);
  60617. $this->configureTestCase($test, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName));
  60618. return $test;
  60619. }
  60620. /**
  60621. * @psalm-param class-string $className
  60622. * @psalm-param non-empty-string $methodName
  60623. * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
  60624. */
  60625. private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings): \PHPUnit\Framework\DataProviderTestSuite
  60626. {
  60627. $dataProviderTestSuite = \PHPUnit\Framework\DataProviderTestSuite::empty($className . '::' . $methodName);
  60628. $groups = (new Groups())->groups($className, $methodName);
  60629. foreach ($data as $_dataName => $_data) {
  60630. $_test = new $className($methodName);
  60631. assert($_test instanceof \PHPUnit\Framework\TestCase);
  60632. $_test->setData($_dataName, $_data);
  60633. $this->configureTestCase($_test, $runTestInSeparateProcess, $preserveGlobalState, $runClassInSeparateProcess, $backupSettings);
  60634. $dataProviderTestSuite->addTest($_test, $groups);
  60635. }
  60636. return $dataProviderTestSuite;
  60637. }
  60638. /**
  60639. * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
  60640. */
  60641. private function configureTestCase(\PHPUnit\Framework\TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings): void
  60642. {
  60643. if ($runTestInSeparateProcess) {
  60644. $test->setRunTestInSeparateProcess(\true);
  60645. }
  60646. if ($runClassInSeparateProcess) {
  60647. $test->setRunClassInSeparateProcess(\true);
  60648. }
  60649. if ($preserveGlobalState !== null) {
  60650. $test->setPreserveGlobalState($preserveGlobalState);
  60651. }
  60652. if ($backupSettings['backupGlobals'] !== null) {
  60653. $test->setBackupGlobals($backupSettings['backupGlobals']);
  60654. } else {
  60655. $test->setBackupGlobals(ConfigurationRegistry::get()->backupGlobals());
  60656. }
  60657. $test->setBackupGlobalsExcludeList($backupSettings['backupGlobalsExcludeList']);
  60658. if ($backupSettings['backupStaticProperties'] !== null) {
  60659. $test->setBackupStaticProperties($backupSettings['backupStaticProperties']);
  60660. } else {
  60661. $test->setBackupStaticProperties(ConfigurationRegistry::get()->backupStaticProperties());
  60662. }
  60663. $test->setBackupStaticPropertiesExcludeList($backupSettings['backupStaticPropertiesExcludeList']);
  60664. }
  60665. /**
  60666. * @psalm-param class-string $className
  60667. * @psalm-param non-empty-string $methodName
  60668. *
  60669. * @psalm-return array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>}
  60670. */
  60671. private function backupSettings(string $className, string $methodName): array
  60672. {
  60673. $metadataForClass = MetadataRegistry::parser()->forClass($className);
  60674. $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName);
  60675. $metadataForClassAndMethod = MetadataRegistry::parser()->forClassAndMethod($className, $methodName);
  60676. $backupGlobals = null;
  60677. $backupGlobalsExcludeList = [];
  60678. if ($metadataForMethod->isBackupGlobals()->isNotEmpty()) {
  60679. $metadata = $metadataForMethod->isBackupGlobals()->asArray()[0];
  60680. assert($metadata instanceof BackupGlobals);
  60681. if ($metadata->enabled()) {
  60682. $backupGlobals = \true;
  60683. }
  60684. } elseif ($metadataForClass->isBackupGlobals()->isNotEmpty()) {
  60685. $metadata = $metadataForClass->isBackupGlobals()->asArray()[0];
  60686. assert($metadata instanceof BackupGlobals);
  60687. if ($metadata->enabled()) {
  60688. $backupGlobals = \true;
  60689. }
  60690. }
  60691. foreach ($metadataForClassAndMethod->isExcludeGlobalVariableFromBackup() as $metadata) {
  60692. assert($metadata instanceof ExcludeGlobalVariableFromBackup);
  60693. $backupGlobalsExcludeList[] = $metadata->globalVariableName();
  60694. }
  60695. $backupStaticProperties = null;
  60696. $backupStaticPropertiesExcludeList = [];
  60697. if ($metadataForMethod->isBackupStaticProperties()->isNotEmpty()) {
  60698. $metadata = $metadataForMethod->isBackupStaticProperties()->asArray()[0];
  60699. assert($metadata instanceof BackupStaticProperties);
  60700. if ($metadata->enabled()) {
  60701. $backupStaticProperties = \true;
  60702. }
  60703. } elseif ($metadataForClass->isBackupStaticProperties()->isNotEmpty()) {
  60704. $metadata = $metadataForClass->isBackupStaticProperties()->asArray()[0];
  60705. assert($metadata instanceof BackupStaticProperties);
  60706. if ($metadata->enabled()) {
  60707. $backupStaticProperties = \true;
  60708. }
  60709. }
  60710. foreach ($metadataForClassAndMethod->isExcludeStaticPropertyFromBackup() as $metadata) {
  60711. assert($metadata instanceof ExcludeStaticPropertyFromBackup);
  60712. if (!isset($backupStaticPropertiesExcludeList[$metadata->className()])) {
  60713. $backupStaticPropertiesExcludeList[$metadata->className()] = [];
  60714. }
  60715. $backupStaticPropertiesExcludeList[$metadata->className()][] = $metadata->propertyName();
  60716. }
  60717. return ['backupGlobals' => $backupGlobals, 'backupGlobalsExcludeList' => $backupGlobalsExcludeList, 'backupStaticProperties' => $backupStaticProperties, 'backupStaticPropertiesExcludeList' => $backupStaticPropertiesExcludeList];
  60718. }
  60719. /**
  60720. * @psalm-param class-string $className
  60721. * @psalm-param non-empty-string $methodName
  60722. */
  60723. private function shouldGlobalStateBePreserved(string $className, string $methodName): ?bool
  60724. {
  60725. $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName);
  60726. if ($metadataForMethod->isPreserveGlobalState()->isNotEmpty()) {
  60727. $metadata = $metadataForMethod->isPreserveGlobalState()->asArray()[0];
  60728. assert($metadata instanceof PreserveGlobalState);
  60729. return $metadata->enabled();
  60730. }
  60731. $metadataForClass = MetadataRegistry::parser()->forClass($className);
  60732. if ($metadataForClass->isPreserveGlobalState()->isNotEmpty()) {
  60733. $metadata = $metadataForClass->isPreserveGlobalState()->asArray()[0];
  60734. assert($metadata instanceof PreserveGlobalState);
  60735. return $metadata->enabled();
  60736. }
  60737. return null;
  60738. }
  60739. /**
  60740. * @psalm-param class-string $className
  60741. * @psalm-param non-empty-string $methodName
  60742. */
  60743. private function shouldTestMethodBeRunInSeparateProcess(string $className, string $methodName): bool
  60744. {
  60745. if (MetadataRegistry::parser()->forClass($className)->isRunTestsInSeparateProcesses()->isNotEmpty()) {
  60746. return \true;
  60747. }
  60748. if (MetadataRegistry::parser()->forMethod($className, $methodName)->isRunInSeparateProcess()->isNotEmpty()) {
  60749. return \true;
  60750. }
  60751. return \false;
  60752. }
  60753. /**
  60754. * @psalm-param class-string $className
  60755. */
  60756. private function shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess(string $className): bool
  60757. {
  60758. return MetadataRegistry::parser()->forClass($className)->isRunClassInSeparateProcess()->isNotEmpty();
  60759. }
  60760. /**
  60761. * @psalm-param class-string $className
  60762. * @psalm-param non-empty-string $methodName
  60763. */
  60764. private function requirementsSatisfied(string $className, string $methodName): bool
  60765. {
  60766. return (new Requirements())->requirementsNotSatisfiedFor($className, $methodName) === [];
  60767. }
  60768. }
  60769. <?php
  60770. declare (strict_types=1);
  60771. /*
  60772. * This file is part of PHPUnit.
  60773. *
  60774. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60775. *
  60776. * For the full copyright and license information, please view the LICENSE
  60777. * file that was distributed with this source code.
  60778. */
  60779. namespace PHPUnit\Framework;
  60780. use const LC_ALL;
  60781. use const LC_COLLATE;
  60782. use const LC_CTYPE;
  60783. use const LC_MONETARY;
  60784. use const LC_NUMERIC;
  60785. use const LC_TIME;
  60786. use const PATHINFO_FILENAME;
  60787. use const PHP_EOL;
  60788. use const PHP_URL_PATH;
  60789. use function array_is_list;
  60790. use function array_keys;
  60791. use function array_map;
  60792. use function array_merge;
  60793. use function array_values;
  60794. use function assert;
  60795. use function basename;
  60796. use function chdir;
  60797. use function class_exists;
  60798. use function clearstatcache;
  60799. use function count;
  60800. use function defined;
  60801. use function explode;
  60802. use function getcwd;
  60803. use function implode;
  60804. use function in_array;
  60805. use function ini_set;
  60806. use function is_array;
  60807. use function is_callable;
  60808. use function is_int;
  60809. use function is_object;
  60810. use function is_string;
  60811. use function libxml_clear_errors;
  60812. use function method_exists;
  60813. use function ob_end_clean;
  60814. use function ob_get_clean;
  60815. use function ob_get_contents;
  60816. use function ob_get_level;
  60817. use function ob_start;
  60818. use function parse_url;
  60819. use function pathinfo;
  60820. use function preg_replace;
  60821. use function setlocale;
  60822. use function sprintf;
  60823. use function str_contains;
  60824. use function trim;
  60825. use AssertionError;
  60826. use PHPUnitPHAR\DeepCopy\DeepCopy;
  60827. use PHPUnit\Event;
  60828. use PHPUnit\Event\NoPreviousThrowableException;
  60829. use PHPUnit\Event\RuntimeException;
  60830. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  60831. use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint;
  60832. use PHPUnit\Framework\Constraint\ExceptionCode;
  60833. use PHPUnit\Framework\Constraint\ExceptionMessageIsOrContains;
  60834. use PHPUnit\Framework\Constraint\ExceptionMessageMatchesRegularExpression;
  60835. use PHPUnit\Framework\MockObject\Exception as MockObjectException;
  60836. use PHPUnit\Framework\MockObject\Generator\Generator as MockGenerator;
  60837. use PHPUnit\Framework\MockObject\MockBuilder;
  60838. use PHPUnit\Framework\MockObject\MockObject;
  60839. use PHPUnit\Framework\MockObject\MockObjectInternal;
  60840. use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
  60841. use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
  60842. use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
  60843. use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
  60844. use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
  60845. use PHPUnit\Framework\MockObject\Stub;
  60846. use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
  60847. use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
  60848. use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
  60849. use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
  60850. use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
  60851. use PHPUnit\Framework\MockObject\Stub\ReturnStub;
  60852. use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
  60853. use PHPUnit\Framework\TestSize\TestSize;
  60854. use PHPUnit\Framework\TestStatus\TestStatus;
  60855. use PHPUnit\Metadata\Api\Groups;
  60856. use PHPUnit\Metadata\Api\HookMethods;
  60857. use PHPUnit\Metadata\Api\Requirements;
  60858. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  60859. use PHPUnit\TestRunner\TestResult\PassedTests;
  60860. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  60861. use PHPUnit\Util\Cloner;
  60862. use PHPUnit\Util\Test as TestUtil;
  60863. use ReflectionClass;
  60864. use ReflectionException;
  60865. use ReflectionMethod;
  60866. use ReflectionObject;
  60867. use ReflectionParameter;
  60868. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
  60869. use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
  60870. use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
  60871. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  60872. use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
  60873. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  60874. use PHPUnitPHAR\SebastianBergmann\GlobalState\ExcludeList as GlobalStateExcludeList;
  60875. use PHPUnitPHAR\SebastianBergmann\GlobalState\Restorer;
  60876. use PHPUnitPHAR\SebastianBergmann\GlobalState\Snapshot;
  60877. use PHPUnitPHAR\SebastianBergmann\Invoker\TimeoutException;
  60878. use PHPUnitPHAR\SebastianBergmann\ObjectEnumerator\Enumerator;
  60879. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  60880. use Throwable;
  60881. /**
  60882. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  60883. */
  60884. abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Framework\Reorderable, \PHPUnit\Framework\SelfDescribing, \PHPUnit\Framework\Test
  60885. {
  60886. private const LOCALE_CATEGORIES = [LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME];
  60887. private ?bool $backupGlobals = null;
  60888. /**
  60889. * @psalm-var list<string>
  60890. */
  60891. private array $backupGlobalsExcludeList = [];
  60892. private ?bool $backupStaticProperties = null;
  60893. /**
  60894. * @psalm-var array<string,list<class-string>>
  60895. */
  60896. private array $backupStaticPropertiesExcludeList = [];
  60897. private ?Snapshot $snapshot = null;
  60898. private ?bool $runClassInSeparateProcess = null;
  60899. private ?bool $runTestInSeparateProcess = null;
  60900. private bool $preserveGlobalState = \false;
  60901. private bool $inIsolation = \false;
  60902. private ?string $expectedException = null;
  60903. private ?string $expectedExceptionMessage = null;
  60904. private ?string $expectedExceptionMessageRegExp = null;
  60905. private null|int|string $expectedExceptionCode = null;
  60906. /**
  60907. * @psalm-var list<ExecutionOrderDependency>
  60908. */
  60909. private array $providedTests = [];
  60910. private array $data = [];
  60911. private int|string $dataName = '';
  60912. /**
  60913. * @psalm-var non-empty-string
  60914. */
  60915. private string $name;
  60916. /**
  60917. * @psalm-var list<string>
  60918. */
  60919. private array $groups = [];
  60920. /**
  60921. * @psalm-var list<ExecutionOrderDependency>
  60922. */
  60923. private array $dependencies = [];
  60924. private array $dependencyInput = [];
  60925. /**
  60926. * @psalm-var array<string,string>
  60927. */
  60928. private array $iniSettings = [];
  60929. private array $locale = [];
  60930. /**
  60931. * @psalm-var list<MockObjectInternal>
  60932. */
  60933. private array $mockObjects = [];
  60934. private bool $registerMockObjectsFromTestArgumentsRecursively = \false;
  60935. private TestStatus $status;
  60936. private int $numberOfAssertionsPerformed = 0;
  60937. private mixed $testResult = null;
  60938. private string $output = '';
  60939. private ?string $outputExpectedRegex = null;
  60940. private ?string $outputExpectedString = null;
  60941. private bool $outputBufferingActive = \false;
  60942. private int $outputBufferingLevel;
  60943. private bool $outputRetrievedForAssertion = \false;
  60944. private bool $doesNotPerformAssertions = \false;
  60945. /**
  60946. * @psalm-var list<Comparator>
  60947. */
  60948. private array $customComparators = [];
  60949. private ?Event\Code\TestMethod $testValueObjectForEvents = null;
  60950. private bool $wasPrepared = \false;
  60951. /**
  60952. * @psalm-var array<class-string, true>
  60953. */
  60954. private array $failureTypes = [];
  60955. /**
  60956. * Returns a matcher that matches when the method is executed
  60957. * zero or more times.
  60958. */
  60959. final public static function any(): AnyInvokedCountMatcher
  60960. {
  60961. return new AnyInvokedCountMatcher();
  60962. }
  60963. /**
  60964. * Returns a matcher that matches when the method is never executed.
  60965. */
  60966. final public static function never(): InvokedCountMatcher
  60967. {
  60968. return new InvokedCountMatcher(0);
  60969. }
  60970. /**
  60971. * Returns a matcher that matches when the method is executed
  60972. * at least N times.
  60973. */
  60974. final public static function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
  60975. {
  60976. return new InvokedAtLeastCountMatcher($requiredInvocations);
  60977. }
  60978. /**
  60979. * Returns a matcher that matches when the method is executed at least once.
  60980. */
  60981. final public static function atLeastOnce(): InvokedAtLeastOnceMatcher
  60982. {
  60983. return new InvokedAtLeastOnceMatcher();
  60984. }
  60985. /**
  60986. * Returns a matcher that matches when the method is executed exactly once.
  60987. */
  60988. final public static function once(): InvokedCountMatcher
  60989. {
  60990. return new InvokedCountMatcher(1);
  60991. }
  60992. /**
  60993. * Returns a matcher that matches when the method is executed
  60994. * exactly $count times.
  60995. */
  60996. final public static function exactly(int $count): InvokedCountMatcher
  60997. {
  60998. return new InvokedCountMatcher($count);
  60999. }
  61000. /**
  61001. * Returns a matcher that matches when the method is executed
  61002. * at most N times.
  61003. */
  61004. final public static function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
  61005. {
  61006. return new InvokedAtMostCountMatcher($allowedInvocations);
  61007. }
  61008. /**
  61009. * @deprecated Use <code>$double->willReturn()</code> instead of <code>$double->will($this->returnValue())</code>
  61010. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61011. *
  61012. * @codeCoverageIgnore
  61013. */
  61014. final public static function returnValue(mixed $value): ReturnStub
  61015. {
  61016. return new ReturnStub($value);
  61017. }
  61018. /**
  61019. * @deprecated Use <code>$double->willReturnMap()</code> instead of <code>$double->will($this->returnValueMap())</code>
  61020. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61021. *
  61022. * @codeCoverageIgnore
  61023. */
  61024. final public static function returnValueMap(array $valueMap): ReturnValueMapStub
  61025. {
  61026. return new ReturnValueMapStub($valueMap);
  61027. }
  61028. /**
  61029. * @deprecated Use <code>$double->willReturnArgument()</code> instead of <code>$double->will($this->returnArgument())</code>
  61030. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61031. *
  61032. * @codeCoverageIgnore
  61033. */
  61034. final public static function returnArgument(int $argumentIndex): ReturnArgumentStub
  61035. {
  61036. return new ReturnArgumentStub($argumentIndex);
  61037. }
  61038. /**
  61039. * @deprecated Use <code>$double->willReturnCallback()</code> instead of <code>$double->will($this->returnCallback())</code>
  61040. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61041. *
  61042. * @codeCoverageIgnore
  61043. */
  61044. final public static function returnCallback(callable $callback): ReturnCallbackStub
  61045. {
  61046. return new ReturnCallbackStub($callback);
  61047. }
  61048. /**
  61049. * @deprecated Use <code>$double->willReturnSelf()</code> instead of <code>$double->will($this->returnSelf())</code>
  61050. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61051. *
  61052. * @codeCoverageIgnore
  61053. */
  61054. final public static function returnSelf(): ReturnSelfStub
  61055. {
  61056. return new ReturnSelfStub();
  61057. }
  61058. final public static function throwException(Throwable $exception): ExceptionStub
  61059. {
  61060. return new ExceptionStub($exception);
  61061. }
  61062. /**
  61063. * @deprecated Use <code>$double->willReturn()</code> instead of <code>$double->will($this->onConsecutiveCalls())</code>
  61064. * @see https://github.com/sebastianbergmann/phpunit/issues/5423
  61065. * @see https://github.com/sebastianbergmann/phpunit/issues/5425
  61066. *
  61067. * @codeCoverageIgnore
  61068. */
  61069. final public static function onConsecutiveCalls(mixed ...$arguments): ConsecutiveCallsStub
  61070. {
  61071. return new ConsecutiveCallsStub($arguments);
  61072. }
  61073. /**
  61074. * @psalm-param non-empty-string $name
  61075. *
  61076. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61077. */
  61078. public function __construct(string $name)
  61079. {
  61080. $this->setName($name);
  61081. $this->status = TestStatus::unknown();
  61082. }
  61083. /**
  61084. * This method is called before the first test of this test class is run.
  61085. *
  61086. * @codeCoverageIgnore
  61087. */
  61088. public static function setUpBeforeClass(): void
  61089. {
  61090. }
  61091. /**
  61092. * This method is called after the last test of this test class is run.
  61093. *
  61094. * @codeCoverageIgnore
  61095. */
  61096. public static function tearDownAfterClass(): void
  61097. {
  61098. }
  61099. /**
  61100. * This method is called before each test.
  61101. *
  61102. * @codeCoverageIgnore
  61103. */
  61104. protected function setUp(): void
  61105. {
  61106. }
  61107. /**
  61108. * Performs assertions shared by all tests of a test case.
  61109. *
  61110. * This method is called between setUp() and test.
  61111. *
  61112. * @codeCoverageIgnore
  61113. */
  61114. protected function assertPreConditions(): void
  61115. {
  61116. }
  61117. /**
  61118. * Performs assertions shared by all tests of a test case.
  61119. *
  61120. * This method is called between test and tearDown().
  61121. *
  61122. * @codeCoverageIgnore
  61123. */
  61124. protected function assertPostConditions(): void
  61125. {
  61126. }
  61127. /**
  61128. * This method is called after each test.
  61129. *
  61130. * @codeCoverageIgnore
  61131. */
  61132. protected function tearDown(): void
  61133. {
  61134. }
  61135. /**
  61136. * Returns a string representation of the test case.
  61137. *
  61138. * @throws Exception
  61139. *
  61140. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61141. */
  61142. public function toString(): string
  61143. {
  61144. $buffer = sprintf('%s::%s', (new ReflectionClass($this))->getName(), $this->name);
  61145. return $buffer . $this->dataSetAsStringWithData();
  61146. }
  61147. /**
  61148. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61149. */
  61150. final public function count(): int
  61151. {
  61152. return 1;
  61153. }
  61154. final public function getActualOutputForAssertion(): string
  61155. {
  61156. $this->outputRetrievedForAssertion = \true;
  61157. return $this->output();
  61158. }
  61159. final public function expectOutputRegex(string $expectedRegex): void
  61160. {
  61161. $this->outputExpectedRegex = $expectedRegex;
  61162. }
  61163. final public function expectOutputString(string $expectedString): void
  61164. {
  61165. $this->outputExpectedString = $expectedString;
  61166. }
  61167. /**
  61168. * @psalm-param class-string<Throwable> $exception
  61169. */
  61170. final public function expectException(string $exception): void
  61171. {
  61172. $this->expectedException = $exception;
  61173. }
  61174. final public function expectExceptionCode(int|string $code): void
  61175. {
  61176. $this->expectedExceptionCode = $code;
  61177. }
  61178. final public function expectExceptionMessage(string $message): void
  61179. {
  61180. $this->expectedExceptionMessage = $message;
  61181. }
  61182. final public function expectExceptionMessageMatches(string $regularExpression): void
  61183. {
  61184. $this->expectedExceptionMessageRegExp = $regularExpression;
  61185. }
  61186. /**
  61187. * Sets up an expectation for an exception to be raised by the code under test.
  61188. * Information for expected exception class, expected exception message, and
  61189. * expected exception code are retrieved from a given Exception object.
  61190. */
  61191. final public function expectExceptionObject(\Exception $exception): void
  61192. {
  61193. $this->expectException($exception::class);
  61194. $this->expectExceptionMessage($exception->getMessage());
  61195. $this->expectExceptionCode($exception->getCode());
  61196. }
  61197. final public function expectNotToPerformAssertions(): void
  61198. {
  61199. $this->doesNotPerformAssertions = \true;
  61200. }
  61201. /**
  61202. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61203. */
  61204. final public function status(): TestStatus
  61205. {
  61206. return $this->status;
  61207. }
  61208. /**
  61209. * @throws \PHPUnit\Runner\Exception
  61210. * @throws \PHPUnit\Util\Exception
  61211. * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
  61212. * @throws \SebastianBergmann\Template\InvalidArgumentException
  61213. * @throws CodeCoverageException
  61214. * @throws Exception
  61215. * @throws MoreThanOneDataSetFromDataProviderException
  61216. * @throws NoPreviousThrowableException
  61217. * @throws ProcessIsolationException
  61218. * @throws UnintentionallyCoveredCodeException
  61219. *
  61220. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61221. */
  61222. final public function run(): void
  61223. {
  61224. if (!$this->handleDependencies()) {
  61225. return;
  61226. }
  61227. if (!$this->shouldRunInSeparateProcess() || $this->requirementsNotSatisfied()) {
  61228. (new \PHPUnit\Framework\TestRunner())->run($this);
  61229. } else {
  61230. (new \PHPUnit\Framework\TestRunner())->runInSeparateProcess($this, $this->runClassInSeparateProcess && !$this->runTestInSeparateProcess, $this->preserveGlobalState);
  61231. }
  61232. }
  61233. /**
  61234. * Returns a builder object to create mock objects using a fluent interface.
  61235. *
  61236. * @psalm-template RealInstanceType of object
  61237. *
  61238. * @psalm-param class-string<RealInstanceType> $className
  61239. *
  61240. * @psalm-return MockBuilder<RealInstanceType>
  61241. */
  61242. final public function getMockBuilder(string $className): MockBuilder
  61243. {
  61244. return new MockBuilder($this, $className);
  61245. }
  61246. /**
  61247. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61248. */
  61249. final public function groups(): array
  61250. {
  61251. return $this->groups;
  61252. }
  61253. /**
  61254. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61255. */
  61256. final public function setGroups(array $groups): void
  61257. {
  61258. $this->groups = $groups;
  61259. }
  61260. /**
  61261. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61262. */
  61263. final public function nameWithDataSet(): string
  61264. {
  61265. return $this->name . $this->dataSetAsString();
  61266. }
  61267. /**
  61268. * @psalm-return non-empty-string
  61269. *
  61270. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61271. */
  61272. final public function name(): string
  61273. {
  61274. return $this->name;
  61275. }
  61276. /**
  61277. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61278. */
  61279. final public function size(): TestSize
  61280. {
  61281. return (new Groups())->size(static::class, $this->name);
  61282. }
  61283. /**
  61284. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61285. */
  61286. final public function hasUnexpectedOutput(): bool
  61287. {
  61288. if ($this->output === '') {
  61289. return \false;
  61290. }
  61291. if ($this->expectsOutput()) {
  61292. return \false;
  61293. }
  61294. return \true;
  61295. }
  61296. /**
  61297. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61298. */
  61299. final public function output(): string
  61300. {
  61301. if (!$this->outputBufferingActive) {
  61302. return $this->output;
  61303. }
  61304. return (string) ob_get_contents();
  61305. }
  61306. /**
  61307. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61308. */
  61309. final public function doesNotPerformAssertions(): bool
  61310. {
  61311. return $this->doesNotPerformAssertions;
  61312. }
  61313. /**
  61314. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61315. */
  61316. final public function expectsOutput(): bool
  61317. {
  61318. return $this->hasExpectationOnOutput() || $this->outputRetrievedForAssertion;
  61319. }
  61320. /**
  61321. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61322. *
  61323. * @deprecated
  61324. *
  61325. * @codeCoverageIgnore
  61326. */
  61327. final public function registerMockObjectsFromTestArgumentsRecursively(): void
  61328. {
  61329. $this->registerMockObjectsFromTestArgumentsRecursively = \true;
  61330. }
  61331. /**
  61332. * @throws Throwable
  61333. *
  61334. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61335. */
  61336. final public function runBare(): void
  61337. {
  61338. $emitter = Event\Facade::emitter();
  61339. $emitter->testPreparationStarted($this->valueObjectForEvents());
  61340. $this->snapshotGlobalState();
  61341. $this->startOutputBuffering();
  61342. clearstatcache();
  61343. $hookMethods = (new HookMethods())->hookMethods(static::class);
  61344. $hasMetRequirements = \false;
  61345. $this->numberOfAssertionsPerformed = 0;
  61346. $currentWorkingDirectory = getcwd();
  61347. try {
  61348. $this->checkRequirements();
  61349. $hasMetRequirements = \true;
  61350. if ($this->inIsolation) {
  61351. // @codeCoverageIgnoreStart
  61352. $this->invokeBeforeClassHookMethods($hookMethods, $emitter);
  61353. // @codeCoverageIgnoreEnd
  61354. }
  61355. if (method_exists(static::class, $this->name) && MetadataRegistry::parser()->forClassAndMethod(static::class, $this->name)->isDoesNotPerformAssertions()->isNotEmpty()) {
  61356. $this->doesNotPerformAssertions = \true;
  61357. }
  61358. $this->invokeBeforeTestHookMethods($hookMethods, $emitter);
  61359. $this->invokePreConditionHookMethods($hookMethods, $emitter);
  61360. $emitter->testPrepared($this->valueObjectForEvents());
  61361. $this->wasPrepared = \true;
  61362. $this->testResult = $this->runTest();
  61363. $this->verifyMockObjects();
  61364. $this->invokePostConditionHookMethods($hookMethods, $emitter);
  61365. $this->status = TestStatus::success();
  61366. } catch (\PHPUnit\Framework\IncompleteTest $e) {
  61367. $this->status = TestStatus::incomplete($e->getMessage());
  61368. $emitter->testMarkedAsIncomplete($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e));
  61369. } catch (\PHPUnit\Framework\SkippedTest $e) {
  61370. $this->status = TestStatus::skipped($e->getMessage());
  61371. $emitter->testSkipped($this->valueObjectForEvents(), $e->getMessage());
  61372. } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) {
  61373. if (!$this->wasPrepared) {
  61374. $this->wasPrepared = \true;
  61375. $emitter->testPreparationFailed($this->valueObjectForEvents());
  61376. }
  61377. $this->status = TestStatus::failure($e->getMessage());
  61378. $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
  61379. } catch (TimeoutException $e) {
  61380. $this->status = TestStatus::risky($e->getMessage());
  61381. } catch (Throwable $_e) {
  61382. if ($this->isRegisteredFailure($_e)) {
  61383. $this->status = TestStatus::failure($_e->getMessage());
  61384. $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($_e), null);
  61385. } else {
  61386. $e = $this->transformException($_e);
  61387. $this->status = TestStatus::error($e->getMessage());
  61388. $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e));
  61389. }
  61390. }
  61391. $outputBufferingStopped = \false;
  61392. if (!isset($e) && $this->hasExpectationOnOutput() && $this->stopOutputBuffering()) {
  61393. $outputBufferingStopped = \true;
  61394. $this->performAssertionsOnOutput();
  61395. }
  61396. if ($this->status->isSuccess()) {
  61397. $emitter->testPassed($this->valueObjectForEvents());
  61398. if (!$this->usesDataProvider()) {
  61399. PassedTests::instance()->testMethodPassed($this->valueObjectForEvents(), $this->testResult);
  61400. }
  61401. }
  61402. try {
  61403. $this->mockObjects = [];
  61404. } catch (Throwable $t) {
  61405. Event\Facade::emitter()->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($t));
  61406. }
  61407. // Tear down the fixture. An exception raised in tearDown() will be
  61408. // caught and passed on when no exception was raised before.
  61409. try {
  61410. if ($hasMetRequirements) {
  61411. $this->invokeAfterTestHookMethods($hookMethods, $emitter);
  61412. if ($this->inIsolation) {
  61413. // @codeCoverageIgnoreStart
  61414. $this->invokeAfterClassHookMethods($hookMethods, $emitter);
  61415. // @codeCoverageIgnoreEnd
  61416. }
  61417. }
  61418. } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) {
  61419. $this->status = TestStatus::failure($e->getMessage());
  61420. $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
  61421. } catch (Throwable $exceptionRaisedDuringTearDown) {
  61422. if (!isset($e)) {
  61423. $this->status = TestStatus::error($exceptionRaisedDuringTearDown->getMessage());
  61424. $e = $exceptionRaisedDuringTearDown;
  61425. $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($exceptionRaisedDuringTearDown));
  61426. }
  61427. }
  61428. if (!$outputBufferingStopped) {
  61429. $this->stopOutputBuffering();
  61430. }
  61431. clearstatcache();
  61432. if ($currentWorkingDirectory !== getcwd()) {
  61433. chdir($currentWorkingDirectory);
  61434. }
  61435. $this->restoreGlobalState();
  61436. $this->unregisterCustomComparators();
  61437. $this->cleanupIniSettings();
  61438. $this->cleanupLocaleSettings();
  61439. libxml_clear_errors();
  61440. $this->testValueObjectForEvents = null;
  61441. if (isset($e)) {
  61442. $this->onNotSuccessfulTest($e);
  61443. }
  61444. }
  61445. /**
  61446. * @psalm-param non-empty-string $name
  61447. *
  61448. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61449. */
  61450. final public function setName(string $name): void
  61451. {
  61452. $this->name = $name;
  61453. if (is_callable($this->sortId(), \true)) {
  61454. $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->sortId())];
  61455. }
  61456. }
  61457. /**
  61458. * @psalm-param list<ExecutionOrderDependency> $dependencies
  61459. *
  61460. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61461. */
  61462. final public function setDependencies(array $dependencies): void
  61463. {
  61464. $this->dependencies = $dependencies;
  61465. }
  61466. /**
  61467. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61468. *
  61469. * @codeCoverageIgnore
  61470. */
  61471. final public function setDependencyInput(array $dependencyInput): void
  61472. {
  61473. $this->dependencyInput = $dependencyInput;
  61474. }
  61475. /**
  61476. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61477. */
  61478. final public function dependencyInput(): array
  61479. {
  61480. return $this->dependencyInput;
  61481. }
  61482. /**
  61483. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61484. */
  61485. final public function hasDependencyInput(): bool
  61486. {
  61487. return !empty($this->dependencyInput);
  61488. }
  61489. /**
  61490. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61491. */
  61492. final public function setBackupGlobals(bool $backupGlobals): void
  61493. {
  61494. $this->backupGlobals = $backupGlobals;
  61495. }
  61496. /**
  61497. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61498. */
  61499. final public function setBackupGlobalsExcludeList(array $backupGlobalsExcludeList): void
  61500. {
  61501. $this->backupGlobalsExcludeList = $backupGlobalsExcludeList;
  61502. }
  61503. /**
  61504. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61505. */
  61506. final public function setBackupStaticProperties(bool $backupStaticProperties): void
  61507. {
  61508. $this->backupStaticProperties = $backupStaticProperties;
  61509. }
  61510. /**
  61511. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61512. */
  61513. final public function setBackupStaticPropertiesExcludeList(array $backupStaticPropertiesExcludeList): void
  61514. {
  61515. $this->backupStaticPropertiesExcludeList = $backupStaticPropertiesExcludeList;
  61516. }
  61517. /**
  61518. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61519. */
  61520. final public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void
  61521. {
  61522. if ($this->runTestInSeparateProcess === null) {
  61523. $this->runTestInSeparateProcess = $runTestInSeparateProcess;
  61524. }
  61525. }
  61526. /**
  61527. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61528. */
  61529. final public function setRunClassInSeparateProcess(bool $runClassInSeparateProcess): void
  61530. {
  61531. $this->runClassInSeparateProcess = $runClassInSeparateProcess;
  61532. }
  61533. /**
  61534. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61535. */
  61536. final public function setPreserveGlobalState(bool $preserveGlobalState): void
  61537. {
  61538. $this->preserveGlobalState = $preserveGlobalState;
  61539. }
  61540. /**
  61541. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61542. *
  61543. * @codeCoverageIgnore
  61544. */
  61545. final public function setInIsolation(bool $inIsolation): void
  61546. {
  61547. $this->inIsolation = $inIsolation;
  61548. }
  61549. /**
  61550. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61551. *
  61552. * @codeCoverageIgnore
  61553. */
  61554. final public function result(): mixed
  61555. {
  61556. return $this->testResult;
  61557. }
  61558. /**
  61559. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61560. */
  61561. final public function setResult(mixed $result): void
  61562. {
  61563. $this->testResult = $result;
  61564. }
  61565. /**
  61566. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61567. */
  61568. final public function registerMockObject(MockObject $mockObject): void
  61569. {
  61570. assert($mockObject instanceof MockObjectInternal);
  61571. $this->mockObjects[] = $mockObject;
  61572. }
  61573. /**
  61574. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61575. */
  61576. final public function addToAssertionCount(int $count): void
  61577. {
  61578. $this->numberOfAssertionsPerformed += $count;
  61579. }
  61580. /**
  61581. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61582. */
  61583. final public function numberOfAssertionsPerformed(): int
  61584. {
  61585. return $this->numberOfAssertionsPerformed;
  61586. }
  61587. /**
  61588. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61589. */
  61590. final public function usesDataProvider(): bool
  61591. {
  61592. return !empty($this->data);
  61593. }
  61594. /**
  61595. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61596. */
  61597. final public function dataName(): int|string
  61598. {
  61599. return $this->dataName;
  61600. }
  61601. /**
  61602. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61603. */
  61604. final public function dataSetAsString(): string
  61605. {
  61606. $buffer = '';
  61607. if (!empty($this->data)) {
  61608. if (is_int($this->dataName)) {
  61609. $buffer .= sprintf(' with data set #%d', $this->dataName);
  61610. } else {
  61611. $buffer .= sprintf(' with data set "%s"', $this->dataName);
  61612. }
  61613. }
  61614. return $buffer;
  61615. }
  61616. /**
  61617. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61618. */
  61619. final public function dataSetAsStringWithData(): string
  61620. {
  61621. if (empty($this->data)) {
  61622. return '';
  61623. }
  61624. return $this->dataSetAsString() . sprintf(' (%s)', (new Exporter())->shortenedRecursiveExport($this->data));
  61625. }
  61626. /**
  61627. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61628. */
  61629. final public function providedData(): array
  61630. {
  61631. return $this->data;
  61632. }
  61633. /**
  61634. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61635. */
  61636. final public function sortId(): string
  61637. {
  61638. $id = $this->name;
  61639. if (!str_contains($id, '::')) {
  61640. $id = static::class . '::' . $id;
  61641. }
  61642. if ($this->usesDataProvider()) {
  61643. $id .= $this->dataSetAsString();
  61644. }
  61645. return $id;
  61646. }
  61647. /**
  61648. * @psalm-return list<ExecutionOrderDependency>
  61649. *
  61650. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61651. */
  61652. final public function provides(): array
  61653. {
  61654. return $this->providedTests;
  61655. }
  61656. /**
  61657. * @psalm-return list<ExecutionOrderDependency>
  61658. *
  61659. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61660. */
  61661. final public function requires(): array
  61662. {
  61663. return $this->dependencies;
  61664. }
  61665. /**
  61666. * @throws RuntimeException
  61667. *
  61668. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61669. */
  61670. final public function setData(int|string $dataName, array $data): void
  61671. {
  61672. $this->dataName = $dataName;
  61673. $this->data = $data;
  61674. if (array_is_list($data)) {
  61675. return;
  61676. }
  61677. try {
  61678. $reflector = new ReflectionMethod($this, $this->name);
  61679. $parameters = array_map(static fn(ReflectionParameter $parameter) => $parameter->name, $reflector->getParameters());
  61680. foreach (array_keys($data) as $parameter) {
  61681. if (is_string($parameter) && !in_array($parameter, $parameters, \true)) {
  61682. Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForEvents(), sprintf('Providing invalid named argument $%s for method %s::%s() is deprecated and will not be supported in PHPUnit 11.0.', $parameter, $this::class, $this->name));
  61683. }
  61684. }
  61685. // @codeCoverageIgnoreStart
  61686. } catch (ReflectionException $e) {
  61687. throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
  61688. }
  61689. // @codeCoverageIgnoreEnd
  61690. }
  61691. /**
  61692. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61693. *
  61694. * @throws MoreThanOneDataSetFromDataProviderException
  61695. */
  61696. final public function valueObjectForEvents(): Event\Code\TestMethod
  61697. {
  61698. if ($this->testValueObjectForEvents !== null) {
  61699. return $this->testValueObjectForEvents;
  61700. }
  61701. $this->testValueObjectForEvents = Event\Code\TestMethodBuilder::fromTestCase($this);
  61702. return $this->testValueObjectForEvents;
  61703. }
  61704. /**
  61705. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61706. */
  61707. final public function wasPrepared(): bool
  61708. {
  61709. return $this->wasPrepared;
  61710. }
  61711. final protected function registerComparator(Comparator $comparator): void
  61712. {
  61713. ComparatorFactory::getInstance()->register($comparator);
  61714. Event\Facade::emitter()->testRegisteredComparator($comparator::class);
  61715. $this->customComparators[] = $comparator;
  61716. }
  61717. /**
  61718. * @psalm-param class-string $classOrInterface
  61719. */
  61720. final protected function registerFailureType(string $classOrInterface): void
  61721. {
  61722. $this->failureTypes[$classOrInterface] = \true;
  61723. }
  61724. /**
  61725. * @throws AssertionFailedError
  61726. * @throws Exception
  61727. * @throws ExpectationFailedException
  61728. * @throws Throwable
  61729. *
  61730. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  61731. */
  61732. protected function runTest(): mixed
  61733. {
  61734. $testArguments = array_merge($this->data, $this->dependencyInput);
  61735. $this->registerMockObjectsFromTestArguments($testArguments);
  61736. try {
  61737. $testResult = $this->{$this->name}(...array_values($testArguments));
  61738. } catch (Throwable $exception) {
  61739. if (!$this->shouldExceptionExpectationsBeVerified($exception)) {
  61740. throw $exception;
  61741. }
  61742. $this->verifyExceptionExpectations($exception);
  61743. return null;
  61744. }
  61745. $this->expectedExceptionWasNotRaised();
  61746. return $testResult;
  61747. }
  61748. /**
  61749. * This method is a wrapper for the ini_set() function that automatically
  61750. * resets the modified php.ini setting to its original value after the
  61751. * test is run.
  61752. *
  61753. * @throws Exception
  61754. *
  61755. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5214
  61756. *
  61757. * @codeCoverageIgnore
  61758. */
  61759. protected function iniSet(string $varName, string $newValue): void
  61760. {
  61761. $currentValue = ini_set($varName, $newValue);
  61762. if ($currentValue !== \false) {
  61763. $this->iniSettings[$varName] = $currentValue;
  61764. } else {
  61765. throw new \PHPUnit\Framework\Exception(sprintf('INI setting "%s" could not be set to "%s".', $varName, $newValue));
  61766. }
  61767. }
  61768. /**
  61769. * This method is a wrapper for the setlocale() function that automatically
  61770. * resets the locale to its original value after the test is run.
  61771. *
  61772. * @throws Exception
  61773. *
  61774. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5216
  61775. *
  61776. * @codeCoverageIgnore
  61777. */
  61778. protected function setLocale(mixed ...$arguments): void
  61779. {
  61780. if (count($arguments) < 2) {
  61781. throw new \PHPUnit\Framework\Exception();
  61782. }
  61783. [$category, $locale] = $arguments;
  61784. if (!in_array($category, self::LOCALE_CATEGORIES, \true)) {
  61785. throw new \PHPUnit\Framework\Exception();
  61786. }
  61787. if (!is_array($locale) && !is_string($locale)) {
  61788. throw new \PHPUnit\Framework\Exception();
  61789. }
  61790. $this->locale[$category] = setlocale($category, '0');
  61791. $result = setlocale(...$arguments);
  61792. if ($result === \false) {
  61793. throw new \PHPUnit\Framework\Exception('The locale functionality is not implemented on your platform, ' . 'the specified locale does not exist or the category name is ' . 'invalid.');
  61794. }
  61795. }
  61796. /**
  61797. * Creates a mock object for the specified interface or class.
  61798. *
  61799. * @psalm-template RealInstanceType of object
  61800. *
  61801. * @psalm-param class-string<RealInstanceType> $originalClassName
  61802. *
  61803. * @psalm-return MockObject&RealInstanceType
  61804. *
  61805. * @throws InvalidArgumentException
  61806. * @throws MockObjectException
  61807. * @throws NoPreviousThrowableException
  61808. */
  61809. protected function createMock(string $originalClassName): MockObject
  61810. {
  61811. $mock = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false);
  61812. assert($mock instanceof $originalClassName);
  61813. assert($mock instanceof MockObject);
  61814. $this->registerMockObject($mock);
  61815. Event\Facade::emitter()->testCreatedMockObject($originalClassName);
  61816. return $mock;
  61817. }
  61818. /**
  61819. * @psalm-param list<class-string> $interfaces
  61820. *
  61821. * @throws MockObjectException
  61822. */
  61823. protected function createMockForIntersectionOfInterfaces(array $interfaces): MockObject
  61824. {
  61825. $mock = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \true);
  61826. assert($mock instanceof MockObject);
  61827. $this->registerMockObject($mock);
  61828. Event\Facade::emitter()->testCreatedMockObjectForIntersectionOfInterfaces($interfaces);
  61829. return $mock;
  61830. }
  61831. /**
  61832. * Creates (and configures) a mock object for the specified interface or class.
  61833. *
  61834. * @psalm-template RealInstanceType of object
  61835. *
  61836. * @psalm-param class-string<RealInstanceType> $originalClassName
  61837. *
  61838. * @psalm-return MockObject&RealInstanceType
  61839. *
  61840. * @throws InvalidArgumentException
  61841. * @throws MockObjectException
  61842. * @throws NoPreviousThrowableException
  61843. */
  61844. protected function createConfiguredMock(string $originalClassName, array $configuration): MockObject
  61845. {
  61846. $o = $this->createMock($originalClassName);
  61847. foreach ($configuration as $method => $return) {
  61848. $o->method($method)->willReturn($return);
  61849. }
  61850. return $o;
  61851. }
  61852. /**
  61853. * Creates a partial mock object for the specified interface or class.
  61854. *
  61855. * @psalm-param list<non-empty-string> $methods
  61856. *
  61857. * @psalm-template RealInstanceType of object
  61858. *
  61859. * @psalm-param class-string<RealInstanceType> $originalClassName
  61860. *
  61861. * @psalm-return MockObject&RealInstanceType
  61862. *
  61863. * @throws InvalidArgumentException
  61864. * @throws MockObjectException
  61865. */
  61866. protected function createPartialMock(string $originalClassName, array $methods): MockObject
  61867. {
  61868. $partialMock = $this->getMockBuilder($originalClassName)->disableOriginalConstructor()->disableOriginalClone()->disableArgumentCloning()->disallowMockingUnknownTypes()->onlyMethods($methods)->getMock();
  61869. Event\Facade::emitter()->testCreatedPartialMockObject($originalClassName, ...$methods);
  61870. return $partialMock;
  61871. }
  61872. /**
  61873. * Creates a test proxy for the specified class.
  61874. *
  61875. * @psalm-template RealInstanceType of object
  61876. *
  61877. * @psalm-param class-string<RealInstanceType> $originalClassName
  61878. *
  61879. * @psalm-return MockObject&RealInstanceType
  61880. *
  61881. * @throws InvalidArgumentException
  61882. * @throws MockObjectException
  61883. *
  61884. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5240
  61885. */
  61886. protected function createTestProxy(string $originalClassName, array $constructorArguments = []): MockObject
  61887. {
  61888. $testProxy = $this->getMockBuilder($originalClassName)->setConstructorArgs($constructorArguments)->enableProxyingToOriginalMethods()->getMock();
  61889. Event\Facade::emitter()->testCreatedTestProxy($originalClassName, $constructorArguments);
  61890. return $testProxy;
  61891. }
  61892. /**
  61893. * Creates a mock object for the specified abstract class with all abstract
  61894. * methods of the class mocked. Concrete methods are not mocked by default.
  61895. * To mock concrete methods, use the 7th parameter ($mockedMethods).
  61896. *
  61897. * @psalm-template RealInstanceType of object
  61898. *
  61899. * @psalm-param class-string<RealInstanceType> $originalClassName
  61900. *
  61901. * @psalm-return MockObject&RealInstanceType
  61902. *
  61903. * @throws InvalidArgumentException
  61904. * @throws MockObjectException
  61905. *
  61906. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241
  61907. */
  61908. protected function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false): MockObject
  61909. {
  61910. $mockObject = (new MockGenerator())->mockObjectForAbstractClass($originalClassName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
  61911. $this->registerMockObject($mockObject);
  61912. Event\Facade::emitter()->testCreatedMockObjectForAbstractClass($originalClassName);
  61913. assert($mockObject instanceof $originalClassName);
  61914. assert($mockObject instanceof MockObject);
  61915. return $mockObject;
  61916. }
  61917. /**
  61918. * Creates a mock object based on the given WSDL file.
  61919. *
  61920. * @throws MockObjectException
  61921. *
  61922. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242
  61923. */
  61924. protected function getMockFromWsdl(string $wsdlFile, string $originalClassName = '', string $mockClassName = '', array $methods = [], bool $callOriginalConstructor = \true, array $options = []): MockObject
  61925. {
  61926. if ($originalClassName === '') {
  61927. $fileName = pathinfo(basename(parse_url($wsdlFile, PHP_URL_PATH)), PATHINFO_FILENAME);
  61928. $originalClassName = preg_replace('/\W/', '', $fileName);
  61929. }
  61930. if (!class_exists($originalClassName)) {
  61931. eval((new MockGenerator())->generateClassFromWsdl($wsdlFile, $originalClassName, $methods, $options));
  61932. }
  61933. $mockObject = (new MockGenerator())->testDouble($originalClassName, \true, $methods, ['', $options], $mockClassName, $callOriginalConstructor, \false, \false);
  61934. Event\Facade::emitter()->testCreatedMockObjectFromWsdl($wsdlFile, $originalClassName, $mockClassName, $methods, $callOriginalConstructor, $options);
  61935. assert($mockObject instanceof MockObject);
  61936. $this->registerMockObject($mockObject);
  61937. return $mockObject;
  61938. }
  61939. /**
  61940. * Creates a mock object for the specified trait with all abstract methods
  61941. * of the trait mocked. Concrete methods to mock can be specified with the
  61942. * `$mockedMethods` parameter.
  61943. *
  61944. * @psalm-param trait-string $traitName
  61945. *
  61946. * @throws InvalidArgumentException
  61947. * @throws MockObjectException
  61948. *
  61949. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
  61950. */
  61951. protected function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false): MockObject
  61952. {
  61953. $mockObject = (new MockGenerator())->mockObjectForTrait($traitName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
  61954. $this->registerMockObject($mockObject);
  61955. Event\Facade::emitter()->testCreatedMockObjectForTrait($traitName);
  61956. return $mockObject;
  61957. }
  61958. /**
  61959. * Creates an object that uses the specified trait.
  61960. *
  61961. * @psalm-param trait-string $traitName
  61962. *
  61963. * @throws MockObjectException
  61964. *
  61965. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244
  61966. */
  61967. protected function getObjectForTrait(string $traitName, array $arguments = [], string $traitClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true): object
  61968. {
  61969. return (new MockGenerator())->objectForTrait($traitName, $traitClassName, $callAutoload, $callOriginalConstructor, $arguments);
  61970. }
  61971. protected function transformException(Throwable $t): Throwable
  61972. {
  61973. return $t;
  61974. }
  61975. /**
  61976. * This method is called when a test method did not execute successfully.
  61977. *
  61978. * @throws Throwable
  61979. */
  61980. protected function onNotSuccessfulTest(Throwable $t): never
  61981. {
  61982. throw $t;
  61983. }
  61984. /**
  61985. * @throws Throwable
  61986. */
  61987. private function verifyMockObjects(): void
  61988. {
  61989. foreach ($this->mockObjects as $mockObject) {
  61990. if ($mockObject->__phpunit_hasMatchers()) {
  61991. $this->numberOfAssertionsPerformed++;
  61992. }
  61993. $mockObject->__phpunit_verify($this->shouldInvocationMockerBeReset($mockObject));
  61994. }
  61995. }
  61996. /**
  61997. * @throws SkippedTest
  61998. */
  61999. private function checkRequirements(): void
  62000. {
  62001. if (!$this->name || !method_exists($this, $this->name)) {
  62002. return;
  62003. }
  62004. $missingRequirements = (new Requirements())->requirementsNotSatisfiedFor(static::class, $this->name);
  62005. if (!empty($missingRequirements)) {
  62006. $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
  62007. }
  62008. }
  62009. private function handleDependencies(): bool
  62010. {
  62011. if ([] === $this->dependencies || $this->inIsolation) {
  62012. return \true;
  62013. }
  62014. $passedTests = PassedTests::instance();
  62015. foreach ($this->dependencies as $dependency) {
  62016. if (!$dependency->isValid()) {
  62017. $this->markErrorForInvalidDependency();
  62018. return \false;
  62019. }
  62020. if ($dependency->targetIsClass()) {
  62021. $dependencyClassName = $dependency->getTargetClassName();
  62022. if (!class_exists($dependencyClassName)) {
  62023. $this->markErrorForInvalidDependency($dependency);
  62024. return \false;
  62025. }
  62026. if (!$passedTests->hasTestClassPassed($dependencyClassName)) {
  62027. $this->markSkippedForMissingDependency($dependency);
  62028. return \false;
  62029. }
  62030. continue;
  62031. }
  62032. $dependencyTarget = $dependency->getTarget();
  62033. if (!$passedTests->hasTestMethodPassed($dependencyTarget)) {
  62034. if (!$this->isCallableTestMethod($dependencyTarget)) {
  62035. $this->markErrorForInvalidDependency($dependency);
  62036. } else {
  62037. $this->markSkippedForMissingDependency($dependency);
  62038. }
  62039. return \false;
  62040. }
  62041. if ($passedTests->isGreaterThan($dependencyTarget, $this->size())) {
  62042. Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), 'This test depends on a test that is larger than itself');
  62043. return \false;
  62044. }
  62045. $returnValue = $passedTests->returnValue($dependencyTarget);
  62046. if ($dependency->deepClone()) {
  62047. $deepCopy = new DeepCopy();
  62048. $deepCopy->skipUncloneable(\false);
  62049. $this->dependencyInput[$dependencyTarget] = $deepCopy->copy($returnValue);
  62050. } elseif ($dependency->shallowClone()) {
  62051. $this->dependencyInput[$dependencyTarget] = clone $returnValue;
  62052. } else {
  62053. $this->dependencyInput[$dependencyTarget] = $returnValue;
  62054. }
  62055. }
  62056. $this->testValueObjectForEvents = null;
  62057. return \true;
  62058. }
  62059. /**
  62060. * @throws Exception
  62061. * @throws MoreThanOneDataSetFromDataProviderException
  62062. * @throws NoPreviousThrowableException
  62063. */
  62064. private function markErrorForInvalidDependency(?\PHPUnit\Framework\ExecutionOrderDependency $dependency = null): void
  62065. {
  62066. $message = 'This test has an invalid dependency';
  62067. if ($dependency !== null) {
  62068. $message = sprintf('This test depends on "%s" which does not exist', $dependency->targetIsClass() ? $dependency->getTargetClassName() : $dependency->getTarget());
  62069. }
  62070. $exception = new \PHPUnit\Framework\InvalidDependencyException($message);
  62071. Event\Facade::emitter()->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($exception));
  62072. $this->status = TestStatus::error($message);
  62073. }
  62074. /**
  62075. * @throws MoreThanOneDataSetFromDataProviderException
  62076. */
  62077. private function markSkippedForMissingDependency(\PHPUnit\Framework\ExecutionOrderDependency $dependency): void
  62078. {
  62079. $message = sprintf('This test depends on "%s" to pass', $dependency->getTarget());
  62080. Event\Facade::emitter()->testSkipped($this->valueObjectForEvents(), $message);
  62081. $this->status = TestStatus::skipped($message);
  62082. }
  62083. private function startOutputBuffering(): void
  62084. {
  62085. ob_start();
  62086. $this->outputBufferingActive = \true;
  62087. $this->outputBufferingLevel = ob_get_level();
  62088. }
  62089. /**
  62090. * @throws MoreThanOneDataSetFromDataProviderException
  62091. */
  62092. private function stopOutputBuffering(): bool
  62093. {
  62094. $bufferingLevel = ob_get_level();
  62095. if ($bufferingLevel !== $this->outputBufferingLevel) {
  62096. if ($bufferingLevel > $this->outputBufferingLevel) {
  62097. $message = 'Test code or tested code did not close its own output buffers';
  62098. } else {
  62099. $message = 'Test code or tested code closed output buffers other than its own';
  62100. }
  62101. while (ob_get_level() >= $this->outputBufferingLevel) {
  62102. ob_end_clean();
  62103. }
  62104. Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), $message);
  62105. $this->status = TestStatus::risky($message);
  62106. return \false;
  62107. }
  62108. $this->output = ob_get_clean();
  62109. $this->outputBufferingActive = \false;
  62110. $this->outputBufferingLevel = ob_get_level();
  62111. return \true;
  62112. }
  62113. private function snapshotGlobalState(): void
  62114. {
  62115. if ($this->runTestInSeparateProcess || $this->inIsolation || !$this->backupGlobals && !$this->backupStaticProperties) {
  62116. return;
  62117. }
  62118. $snapshot = $this->createGlobalStateSnapshot($this->backupGlobals === \true);
  62119. $this->snapshot = $snapshot;
  62120. }
  62121. /**
  62122. * @throws MoreThanOneDataSetFromDataProviderException
  62123. */
  62124. private function restoreGlobalState(): void
  62125. {
  62126. if (!$this->snapshot instanceof Snapshot) {
  62127. return;
  62128. }
  62129. if (ConfigurationRegistry::get()->beStrictAboutChangesToGlobalState()) {
  62130. $this->compareGlobalStateSnapshots($this->snapshot, $this->createGlobalStateSnapshot($this->backupGlobals === \true));
  62131. }
  62132. $restorer = new Restorer();
  62133. if ($this->backupGlobals) {
  62134. $restorer->restoreGlobalVariables($this->snapshot);
  62135. }
  62136. if ($this->backupStaticProperties) {
  62137. $restorer->restoreStaticProperties($this->snapshot);
  62138. }
  62139. $this->snapshot = null;
  62140. }
  62141. private function createGlobalStateSnapshot(bool $backupGlobals): Snapshot
  62142. {
  62143. $excludeList = new GlobalStateExcludeList();
  62144. foreach ($this->backupGlobalsExcludeList as $globalVariable) {
  62145. $excludeList->addGlobalVariable($globalVariable);
  62146. }
  62147. if (!defined('PHPUNIT_TESTSUITE')) {
  62148. $excludeList->addClassNamePrefix('PHPUnit');
  62149. $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\CodeCoverage');
  62150. $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\FileIterator');
  62151. $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Invoker');
  62152. $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Template');
  62153. $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Timer');
  62154. $excludeList->addStaticProperty(ComparatorFactory::class, 'instance');
  62155. foreach ($this->backupStaticPropertiesExcludeList as $class => $properties) {
  62156. foreach ($properties as $property) {
  62157. $excludeList->addStaticProperty($class, $property);
  62158. }
  62159. }
  62160. }
  62161. return new Snapshot($excludeList, $backupGlobals, (bool) $this->backupStaticProperties, \false, \false, \false, \false, \false, \false, \false);
  62162. }
  62163. /**
  62164. * @throws MoreThanOneDataSetFromDataProviderException
  62165. */
  62166. private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after): void
  62167. {
  62168. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals;
  62169. if ($backupGlobals) {
  62170. $this->compareGlobalStateSnapshotPart($before->globalVariables(), $after->globalVariables(), "--- Global variables before the test\n+++ Global variables after the test\n");
  62171. $this->compareGlobalStateSnapshotPart($before->superGlobalVariables(), $after->superGlobalVariables(), "--- Super-global variables before the test\n+++ Super-global variables after the test\n");
  62172. }
  62173. if ($this->backupStaticProperties) {
  62174. $this->compareGlobalStateSnapshotPart($before->staticProperties(), $after->staticProperties(), "--- Static properties before the test\n+++ Static properties after the test\n");
  62175. }
  62176. }
  62177. /**
  62178. * @throws MoreThanOneDataSetFromDataProviderException
  62179. */
  62180. private function compareGlobalStateSnapshotPart(array $before, array $after, string $header): void
  62181. {
  62182. if ($before != $after) {
  62183. $differ = new Differ(new UnifiedDiffOutputBuilder($header));
  62184. $exporter = new Exporter();
  62185. Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), 'This test modified global state but was not expected to do so' . PHP_EOL . trim($differ->diff($exporter->export($before), $exporter->export($after))));
  62186. }
  62187. }
  62188. private function shouldInvocationMockerBeReset(MockObject $mock): bool
  62189. {
  62190. $enumerator = new Enumerator();
  62191. if (in_array($mock, $enumerator->enumerate($this->dependencyInput), \true)) {
  62192. return \false;
  62193. }
  62194. if (!is_array($this->testResult) && !is_object($this->testResult)) {
  62195. return \true;
  62196. }
  62197. return !in_array($mock, $enumerator->enumerate($this->testResult), \true);
  62198. }
  62199. /**
  62200. * @deprecated
  62201. */
  62202. private function registerMockObjectsFromTestArguments(array $testArguments, Context $context = new Context()): void
  62203. {
  62204. if ($this->registerMockObjectsFromTestArgumentsRecursively) {
  62205. foreach ((new Enumerator())->enumerate($testArguments) as $object) {
  62206. if ($object instanceof MockObject) {
  62207. $this->registerMockObject($object);
  62208. }
  62209. }
  62210. } else {
  62211. foreach ($testArguments as &$testArgument) {
  62212. if ($testArgument instanceof MockObject) {
  62213. $testArgument = Cloner::clone($testArgument);
  62214. $this->registerMockObject($testArgument);
  62215. } elseif (is_array($testArgument) && !$context->contains($testArgument)) {
  62216. $testArgumentCopy = $testArgument;
  62217. $context->add($testArgument);
  62218. $this->registerMockObjectsFromTestArguments($testArgumentCopy, $context);
  62219. }
  62220. }
  62221. }
  62222. }
  62223. private function unregisterCustomComparators(): void
  62224. {
  62225. $factory = ComparatorFactory::getInstance();
  62226. foreach ($this->customComparators as $comparator) {
  62227. $factory->unregister($comparator);
  62228. }
  62229. $this->customComparators = [];
  62230. }
  62231. private function cleanupIniSettings(): void
  62232. {
  62233. foreach ($this->iniSettings as $varName => $oldValue) {
  62234. ini_set($varName, $oldValue);
  62235. }
  62236. $this->iniSettings = [];
  62237. }
  62238. private function cleanupLocaleSettings(): void
  62239. {
  62240. foreach ($this->locale as $category => $locale) {
  62241. setlocale($category, $locale);
  62242. }
  62243. $this->locale = [];
  62244. }
  62245. /**
  62246. * @throws Exception
  62247. */
  62248. private function shouldExceptionExpectationsBeVerified(Throwable $throwable): bool
  62249. {
  62250. $result = \false;
  62251. if ($this->expectedException !== null || $this->expectedExceptionCode !== null || $this->expectedExceptionMessage !== null || $this->expectedExceptionMessageRegExp !== null) {
  62252. $result = \true;
  62253. }
  62254. if ($throwable instanceof \PHPUnit\Framework\Exception) {
  62255. $result = \false;
  62256. }
  62257. if (is_string($this->expectedException)) {
  62258. try {
  62259. $reflector = new ReflectionClass($this->expectedException);
  62260. // @codeCoverageIgnoreStart
  62261. } catch (ReflectionException $e) {
  62262. throw new \PHPUnit\Framework\Exception($e->getMessage(), $e->getCode(), $e);
  62263. }
  62264. // @codeCoverageIgnoreEnd
  62265. if ($this->expectedException === 'PHPUnit\Framework\Exception' || $this->expectedException === '\PHPUnit\Framework\Exception' || $reflector->isSubclassOf(\PHPUnit\Framework\Exception::class)) {
  62266. $result = \true;
  62267. }
  62268. }
  62269. return $result;
  62270. }
  62271. private function shouldRunInSeparateProcess(): bool
  62272. {
  62273. if ($this->inIsolation) {
  62274. return \false;
  62275. }
  62276. if ($this->runTestInSeparateProcess) {
  62277. return \true;
  62278. }
  62279. if ($this->runClassInSeparateProcess) {
  62280. return \true;
  62281. }
  62282. return ConfigurationRegistry::get()->processIsolation();
  62283. }
  62284. private function isCallableTestMethod(string $dependency): bool
  62285. {
  62286. [$className, $methodName] = explode('::', $dependency);
  62287. if (!class_exists($className)) {
  62288. return \false;
  62289. }
  62290. $class = new ReflectionClass($className);
  62291. if (!$class->isSubclassOf(__CLASS__)) {
  62292. return \false;
  62293. }
  62294. if (!$class->hasMethod($methodName)) {
  62295. return \false;
  62296. }
  62297. return TestUtil::isTestMethod($class->getMethod($methodName));
  62298. }
  62299. /**
  62300. * @throws Exception
  62301. * @throws ExpectationFailedException
  62302. * @throws MoreThanOneDataSetFromDataProviderException
  62303. * @throws NoPreviousThrowableException
  62304. */
  62305. private function performAssertionsOnOutput(): void
  62306. {
  62307. try {
  62308. if ($this->outputExpectedRegex !== null) {
  62309. $this->assertMatchesRegularExpression($this->outputExpectedRegex, $this->output);
  62310. } elseif ($this->outputExpectedString !== null) {
  62311. $this->assertSame($this->outputExpectedString, $this->output);
  62312. }
  62313. } catch (\PHPUnit\Framework\ExpectationFailedException $e) {
  62314. $this->status = TestStatus::failure($e->getMessage());
  62315. Event\Facade::emitter()->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
  62316. throw $e;
  62317. }
  62318. }
  62319. /**
  62320. * @throws Throwable
  62321. *
  62322. * @codeCoverageIgnore
  62323. */
  62324. private function invokeBeforeClassHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62325. {
  62326. $this->invokeHookMethods($hookMethods['beforeClass'], $emitter, 'testBeforeFirstTestMethodCalled', 'testBeforeFirstTestMethodFinished');
  62327. }
  62328. /**
  62329. * @throws Throwable
  62330. */
  62331. private function invokeBeforeTestHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62332. {
  62333. $this->invokeHookMethods($hookMethods['before'], $emitter, 'testBeforeTestMethodCalled', 'testBeforeTestMethodFinished');
  62334. }
  62335. /**
  62336. * @throws Throwable
  62337. */
  62338. private function invokePreConditionHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62339. {
  62340. $this->invokeHookMethods($hookMethods['preCondition'], $emitter, 'testPreConditionCalled', 'testPreConditionFinished');
  62341. }
  62342. /**
  62343. * @throws Throwable
  62344. */
  62345. private function invokePostConditionHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62346. {
  62347. $this->invokeHookMethods($hookMethods['postCondition'], $emitter, 'testPostConditionCalled', 'testPostConditionFinished');
  62348. }
  62349. /**
  62350. * @throws Throwable
  62351. */
  62352. private function invokeAfterTestHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62353. {
  62354. $this->invokeHookMethods($hookMethods['after'], $emitter, 'testAfterTestMethodCalled', 'testAfterTestMethodFinished');
  62355. }
  62356. /**
  62357. * @throws Throwable
  62358. *
  62359. * @codeCoverageIgnore
  62360. */
  62361. private function invokeAfterClassHookMethods(array $hookMethods, Event\Emitter $emitter): void
  62362. {
  62363. $this->invokeHookMethods($hookMethods['afterClass'], $emitter, 'testAfterLastTestMethodCalled', 'testAfterLastTestMethodFinished');
  62364. }
  62365. /**
  62366. * @psalm-param list<non-empty-string> $hookMethods
  62367. * @psalm-param 'testBeforeFirstTestMethodCalled'|'testBeforeTestMethodCalled'|'testPreConditionCalled'|'testPostConditionCalled'|'testAfterTestMethodCalled'|'testAfterLastTestMethodCalled' $calledMethod
  62368. * @psalm-param 'testBeforeFirstTestMethodFinished'|'testBeforeTestMethodFinished'|'testPreConditionFinished'|'testPostConditionFinished'|'testAfterTestMethodFinished'|'testAfterLastTestMethodFinished' $finishedMethod
  62369. *
  62370. * @throws Throwable
  62371. */
  62372. private function invokeHookMethods(array $hookMethods, Event\Emitter $emitter, string $calledMethod, string $finishedMethod): void
  62373. {
  62374. $methodsInvoked = [];
  62375. foreach ($hookMethods as $methodName) {
  62376. if ($this->methodDoesNotExistOrIsDeclaredInTestCase($methodName)) {
  62377. continue;
  62378. }
  62379. try {
  62380. $this->{$methodName}();
  62381. } catch (Throwable $t) {
  62382. }
  62383. $methodInvoked = new Event\Code\ClassMethod(static::class, $methodName);
  62384. $emitter->{$calledMethod}(static::class, $methodInvoked);
  62385. $methodsInvoked[] = $methodInvoked;
  62386. if (isset($t)) {
  62387. break;
  62388. }
  62389. }
  62390. if (!empty($methodsInvoked)) {
  62391. $emitter->{$finishedMethod}(static::class, ...$methodsInvoked);
  62392. }
  62393. if (isset($t)) {
  62394. throw $t;
  62395. }
  62396. }
  62397. private function methodDoesNotExistOrIsDeclaredInTestCase(string $methodName): bool
  62398. {
  62399. $reflector = new ReflectionObject($this);
  62400. return !$reflector->hasMethod($methodName) || $reflector->getMethod($methodName)->getDeclaringClass()->getName() === self::class;
  62401. }
  62402. /**
  62403. * @throws ExpectationFailedException
  62404. */
  62405. private function verifyExceptionExpectations(\Exception|Throwable $exception): void
  62406. {
  62407. if ($this->expectedException !== null) {
  62408. $this->assertThat($exception, new ExceptionConstraint($this->expectedException));
  62409. }
  62410. if ($this->expectedExceptionMessage !== null) {
  62411. $this->assertThat($exception->getMessage(), new ExceptionMessageIsOrContains($this->expectedExceptionMessage));
  62412. }
  62413. if ($this->expectedExceptionMessageRegExp !== null) {
  62414. $this->assertThat($exception->getMessage(), new ExceptionMessageMatchesRegularExpression($this->expectedExceptionMessageRegExp));
  62415. }
  62416. if ($this->expectedExceptionCode !== null) {
  62417. $this->assertThat($exception->getCode(), new ExceptionCode($this->expectedExceptionCode));
  62418. }
  62419. }
  62420. /**
  62421. * @throws AssertionFailedError
  62422. */
  62423. private function expectedExceptionWasNotRaised(): void
  62424. {
  62425. if ($this->expectedException !== null) {
  62426. $this->assertThat(null, new ExceptionConstraint($this->expectedException));
  62427. } elseif ($this->expectedExceptionMessage !== null) {
  62428. $this->numberOfAssertionsPerformed++;
  62429. throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with message "%s" is thrown', $this->expectedExceptionMessage));
  62430. } elseif ($this->expectedExceptionMessageRegExp !== null) {
  62431. $this->numberOfAssertionsPerformed++;
  62432. throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with message matching "%s" is thrown', $this->expectedExceptionMessageRegExp));
  62433. } elseif ($this->expectedExceptionCode !== null) {
  62434. $this->numberOfAssertionsPerformed++;
  62435. throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with code "%s" is thrown', $this->expectedExceptionCode));
  62436. }
  62437. }
  62438. private function isRegisteredFailure(Throwable $t): bool
  62439. {
  62440. foreach (array_keys($this->failureTypes) as $failureType) {
  62441. if ($t instanceof $failureType) {
  62442. return \true;
  62443. }
  62444. }
  62445. return \false;
  62446. }
  62447. /**
  62448. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  62449. */
  62450. private function hasExpectationOnOutput(): bool
  62451. {
  62452. return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
  62453. }
  62454. private function requirementsNotSatisfied(): bool
  62455. {
  62456. return (new Requirements())->requirementsNotSatisfiedFor(static::class, $this->name) !== [];
  62457. }
  62458. /**
  62459. * Creates a test stub for the specified interface or class.
  62460. *
  62461. * @psalm-template RealInstanceType of object
  62462. *
  62463. * @psalm-param class-string<RealInstanceType> $originalClassName
  62464. *
  62465. * @psalm-return Stub&RealInstanceType
  62466. *
  62467. * @throws InvalidArgumentException
  62468. * @throws MockObjectException
  62469. * @throws NoPreviousThrowableException
  62470. */
  62471. protected static function createStub(string $originalClassName): Stub
  62472. {
  62473. $stub = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false);
  62474. Event\Facade::emitter()->testCreatedStub($originalClassName);
  62475. assert($stub instanceof $originalClassName);
  62476. assert($stub instanceof Stub);
  62477. return $stub;
  62478. }
  62479. /**
  62480. * @psalm-param list<class-string> $interfaces
  62481. *
  62482. * @throws MockObjectException
  62483. */
  62484. protected static function createStubForIntersectionOfInterfaces(array $interfaces): Stub
  62485. {
  62486. $stub = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \true);
  62487. Event\Facade::emitter()->testCreatedStubForIntersectionOfInterfaces($interfaces);
  62488. return $stub;
  62489. }
  62490. /**
  62491. * Creates (and configures) a test stub for the specified interface or class.
  62492. *
  62493. * @psalm-template RealInstanceType of object
  62494. *
  62495. * @psalm-param class-string<RealInstanceType> $originalClassName
  62496. *
  62497. * @psalm-return Stub&RealInstanceType
  62498. *
  62499. * @throws InvalidArgumentException
  62500. * @throws MockObjectException
  62501. * @throws NoPreviousThrowableException
  62502. */
  62503. final protected static function createConfiguredStub(string $originalClassName, array $configuration): Stub
  62504. {
  62505. $o = self::createStub($originalClassName);
  62506. foreach ($configuration as $method => $return) {
  62507. $o->method($method)->willReturn($return);
  62508. }
  62509. return $o;
  62510. }
  62511. }
  62512. <?php
  62513. declare (strict_types=1);
  62514. /*
  62515. * This file is part of PHPUnit.
  62516. *
  62517. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62518. *
  62519. * For the full copyright and license information, please view the LICENSE
  62520. * file that was distributed with this source code.
  62521. */
  62522. namespace PHPUnit\Framework;
  62523. use const PHP_EOL;
  62524. use function assert;
  62525. use function defined;
  62526. use function error_clear_last;
  62527. use function extension_loaded;
  62528. use function get_include_path;
  62529. use function hrtime;
  62530. use function serialize;
  62531. use function sprintf;
  62532. use function sys_get_temp_dir;
  62533. use function tempnam;
  62534. use function unlink;
  62535. use function var_export;
  62536. use AssertionError;
  62537. use PHPUnit\Event;
  62538. use PHPUnit\Event\NoPreviousThrowableException;
  62539. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  62540. use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi;
  62541. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  62542. use PHPUnit\Runner\CodeCoverage;
  62543. use PHPUnit\Runner\ErrorHandler;
  62544. use PHPUnit\TextUI\Configuration\Configuration;
  62545. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  62546. use PHPUnit\Util\GlobalState;
  62547. use PHPUnit\Util\PHP\AbstractPhpProcess;
  62548. use ReflectionClass;
  62549. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException;
  62550. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
  62551. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
  62552. use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
  62553. use PHPUnitPHAR\SebastianBergmann\Invoker\TimeoutException;
  62554. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  62555. use Throwable;
  62556. /**
  62557. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62558. *
  62559. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62560. */
  62561. final class TestRunner
  62562. {
  62563. private ?bool $timeLimitCanBeEnforced = null;
  62564. private readonly Configuration $configuration;
  62565. public function __construct()
  62566. {
  62567. $this->configuration = ConfigurationRegistry::get();
  62568. }
  62569. /**
  62570. * @throws \PHPUnit\Runner\Exception
  62571. * @throws CodeCoverageException
  62572. * @throws InvalidArgumentException
  62573. * @throws MoreThanOneDataSetFromDataProviderException
  62574. * @throws UnintentionallyCoveredCodeException
  62575. */
  62576. public function run(\PHPUnit\Framework\TestCase $test): void
  62577. {
  62578. \PHPUnit\Framework\Assert::resetCount();
  62579. if ($this->configuration->registerMockObjectsFromTestArgumentsRecursively()) {
  62580. $test->registerMockObjectsFromTestArgumentsRecursively();
  62581. }
  62582. $shouldCodeCoverageBeCollected = (new CodeCoverageMetadataApi())->shouldCodeCoverageBeCollectedFor($test::class, $test->name());
  62583. $error = \false;
  62584. $failure = \false;
  62585. $incomplete = \false;
  62586. $risky = \false;
  62587. $skipped = \false;
  62588. error_clear_last();
  62589. if ($this->shouldErrorHandlerBeUsed($test)) {
  62590. ErrorHandler::instance()->enable();
  62591. }
  62592. $collectCodeCoverage = CodeCoverage::instance()->isActive() && $shouldCodeCoverageBeCollected;
  62593. if ($collectCodeCoverage) {
  62594. CodeCoverage::instance()->start($test);
  62595. }
  62596. try {
  62597. if ($this->canTimeLimitBeEnforced() && $this->shouldTimeLimitBeEnforced($test)) {
  62598. $risky = $this->runTestWithTimeout($test);
  62599. } else {
  62600. $test->runBare();
  62601. }
  62602. } catch (\PHPUnit\Framework\AssertionFailedError $e) {
  62603. $failure = \true;
  62604. if ($e instanceof \PHPUnit\Framework\IncompleteTestError) {
  62605. $incomplete = \true;
  62606. } elseif ($e instanceof \PHPUnit\Framework\SkippedTest) {
  62607. $skipped = \true;
  62608. }
  62609. } catch (AssertionError $e) {
  62610. $test->addToAssertionCount(1);
  62611. $failure = \true;
  62612. $frame = $e->getTrace()[0];
  62613. assert(isset($frame['file']));
  62614. assert(isset($frame['line']));
  62615. $e = new \PHPUnit\Framework\AssertionFailedError(sprintf('%s in %s:%s', $e->getMessage(), $frame['file'], $frame['line']));
  62616. } catch (Throwable $e) {
  62617. $error = \true;
  62618. }
  62619. $test->addToAssertionCount(\PHPUnit\Framework\Assert::getCount());
  62620. if ($this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) {
  62621. $risky = \true;
  62622. }
  62623. if (!$error && !$failure && !$incomplete && !$skipped && !$risky && $this->configuration->requireCoverageMetadata() && !$this->hasCoverageMetadata($test::class, $test->name())) {
  62624. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test does not define a code coverage target but is expected to do so');
  62625. $risky = \true;
  62626. }
  62627. if ($collectCodeCoverage) {
  62628. $append = !$risky && !$incomplete && !$skipped;
  62629. $linesToBeCovered = [];
  62630. $linesToBeUsed = [];
  62631. if ($append) {
  62632. try {
  62633. $linesToBeCovered = (new CodeCoverageMetadataApi())->linesToBeCovered($test::class, $test->name());
  62634. $linesToBeUsed = (new CodeCoverageMetadataApi())->linesToBeUsed($test::class, $test->name());
  62635. } catch (\PHPUnit\Framework\InvalidCoversTargetException $cce) {
  62636. Event\Facade::emitter()->testTriggeredPhpunitWarning($test->valueObjectForEvents(), $cce->getMessage());
  62637. $append = \false;
  62638. }
  62639. }
  62640. try {
  62641. CodeCoverage::instance()->stop($append, $linesToBeCovered, $linesToBeUsed);
  62642. } catch (UnintentionallyCoveredCodeException $cce) {
  62643. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test executed code that is not listed as code to be covered or used:' . PHP_EOL . $cce->getMessage());
  62644. } catch (OriginalCodeCoverageException $cce) {
  62645. $error = \true;
  62646. $e = $e ?? $cce;
  62647. }
  62648. }
  62649. ErrorHandler::instance()->disable();
  62650. if (!$error && !$incomplete && !$skipped && $this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) {
  62651. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test did not perform any assertions');
  62652. }
  62653. if ($test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() > 0) {
  62654. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test is not expected to perform assertions but performed %d assertion%s', $test->numberOfAssertionsPerformed(), $test->numberOfAssertionsPerformed() > 1 ? 's' : ''));
  62655. }
  62656. if ($test->hasUnexpectedOutput()) {
  62657. Event\Facade::emitter()->testPrintedUnexpectedOutput($test->output());
  62658. }
  62659. if ($this->configuration->disallowTestOutput() && $test->hasUnexpectedOutput()) {
  62660. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test printed output: %s', $test->output()));
  62661. }
  62662. if ($test->wasPrepared()) {
  62663. Event\Facade::emitter()->testFinished($test->valueObjectForEvents(), $test->numberOfAssertionsPerformed());
  62664. }
  62665. }
  62666. /**
  62667. * @throws \PHPUnit\Runner\Exception
  62668. * @throws \PHPUnit\Util\Exception
  62669. * @throws \SebastianBergmann\Template\InvalidArgumentException
  62670. * @throws Exception
  62671. * @throws MoreThanOneDataSetFromDataProviderException
  62672. * @throws NoPreviousThrowableException
  62673. * @throws ProcessIsolationException
  62674. */
  62675. public function runInSeparateProcess(\PHPUnit\Framework\TestCase $test, bool $runEntireClass, bool $preserveGlobalState): void
  62676. {
  62677. $class = new ReflectionClass($test);
  62678. if ($runEntireClass) {
  62679. $template = new Template(__DIR__ . '/../Util/PHP/Template/TestCaseClass.tpl');
  62680. } else {
  62681. $template = new Template(__DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl');
  62682. }
  62683. $bootstrap = '';
  62684. $constants = '';
  62685. $globals = '';
  62686. $includedFiles = '';
  62687. $iniSettings = '';
  62688. if (ConfigurationRegistry::get()->hasBootstrap()) {
  62689. $bootstrap = ConfigurationRegistry::get()->bootstrap();
  62690. }
  62691. if ($preserveGlobalState) {
  62692. $constants = GlobalState::getConstantsAsString();
  62693. $globals = GlobalState::getGlobalsAsString();
  62694. $includedFiles = GlobalState::getIncludedFilesAsString();
  62695. $iniSettings = GlobalState::getIniSettingsAsString();
  62696. }
  62697. $exportObjects = Event\Facade::emitter()->exportsObjects() ? 'true' : 'false';
  62698. $coverage = CodeCoverage::instance()->isActive() ? 'true' : 'false';
  62699. $linesToBeIgnored = var_export(CodeCoverage::instance()->linesToBeIgnored(), \true);
  62700. if (defined('PHPUNIT_COMPOSER_INSTALL')) {
  62701. $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, \true);
  62702. } else {
  62703. $composerAutoload = '\'\'';
  62704. }
  62705. if (defined('__PHPUNIT_PHAR__')) {
  62706. $phar = var_export(__PHPUNIT_PHAR__, \true);
  62707. } else {
  62708. $phar = '\'\'';
  62709. }
  62710. $data = var_export(serialize($test->providedData()), \true);
  62711. $dataName = var_export($test->dataName(), \true);
  62712. $dependencyInput = var_export(serialize($test->dependencyInput()), \true);
  62713. $includePath = var_export(get_include_path(), \true);
  62714. // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
  62715. // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
  62716. $data = "'." . $data . ".'";
  62717. $dataName = "'.(" . $dataName . ").'";
  62718. $dependencyInput = "'." . $dependencyInput . ".'";
  62719. $includePath = "'." . $includePath . ".'";
  62720. $offset = hrtime();
  62721. $serializedConfiguration = $this->saveConfigurationForChildProcess();
  62722. $processResultFile = tempnam(sys_get_temp_dir(), 'phpunit_');
  62723. $var = ['bootstrap' => $bootstrap, 'composerAutoload' => $composerAutoload, 'phar' => $phar, 'filename' => $class->getFileName(), 'className' => $class->getName(), 'collectCodeCoverageInformation' => $coverage, 'linesToBeIgnored' => $linesToBeIgnored, 'data' => $data, 'dataName' => $dataName, 'dependencyInput' => $dependencyInput, 'constants' => $constants, 'globals' => $globals, 'include_path' => $includePath, 'included_files' => $includedFiles, 'iniSettings' => $iniSettings, 'name' => $test->name(), 'offsetSeconds' => $offset[0], 'offsetNanoseconds' => $offset[1], 'serializedConfiguration' => $serializedConfiguration, 'processResultFile' => $processResultFile, 'exportObjects' => $exportObjects];
  62724. if (!$runEntireClass) {
  62725. $var['methodName'] = $test->name();
  62726. }
  62727. $template->setVar($var);
  62728. $php = AbstractPhpProcess::factory();
  62729. $php->runTestJob($template->render(), $test, $processResultFile);
  62730. @unlink($serializedConfiguration);
  62731. }
  62732. /**
  62733. * @psalm-param class-string $className
  62734. * @psalm-param non-empty-string $methodName
  62735. */
  62736. private function hasCoverageMetadata(string $className, string $methodName): bool
  62737. {
  62738. foreach (MetadataRegistry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
  62739. if ($metadata->isCovers()) {
  62740. return \true;
  62741. }
  62742. if ($metadata->isCoversClass()) {
  62743. return \true;
  62744. }
  62745. if ($metadata->isCoversFunction()) {
  62746. return \true;
  62747. }
  62748. if ($metadata->isCoversNothing()) {
  62749. return \true;
  62750. }
  62751. }
  62752. return \false;
  62753. }
  62754. private function canTimeLimitBeEnforced(): bool
  62755. {
  62756. if ($this->timeLimitCanBeEnforced !== null) {
  62757. return $this->timeLimitCanBeEnforced;
  62758. }
  62759. $this->timeLimitCanBeEnforced = (new Invoker())->canInvokeWithTimeout();
  62760. return $this->timeLimitCanBeEnforced;
  62761. }
  62762. private function shouldTimeLimitBeEnforced(\PHPUnit\Framework\TestCase $test): bool
  62763. {
  62764. if (!$this->configuration->enforceTimeLimit()) {
  62765. return \false;
  62766. }
  62767. if (!($this->configuration->defaultTimeLimit() || $test->size()->isKnown())) {
  62768. return \false;
  62769. }
  62770. if (extension_loaded('xdebug') && xdebug_is_debugger_active()) {
  62771. return \false;
  62772. }
  62773. return \true;
  62774. }
  62775. /**
  62776. * @throws Throwable
  62777. */
  62778. private function runTestWithTimeout(\PHPUnit\Framework\TestCase $test): bool
  62779. {
  62780. $_timeout = $this->configuration->defaultTimeLimit();
  62781. $testSize = $test->size();
  62782. if ($testSize->isSmall()) {
  62783. $_timeout = $this->configuration->timeoutForSmallTests();
  62784. } elseif ($testSize->isMedium()) {
  62785. $_timeout = $this->configuration->timeoutForMediumTests();
  62786. } elseif ($testSize->isLarge()) {
  62787. $_timeout = $this->configuration->timeoutForLargeTests();
  62788. }
  62789. try {
  62790. (new Invoker())->invoke([$test, 'runBare'], [], $_timeout);
  62791. } catch (TimeoutException) {
  62792. Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test was aborted after %d second%s', $_timeout, $_timeout !== 1 ? 's' : ''));
  62793. return \true;
  62794. }
  62795. return \false;
  62796. }
  62797. /**
  62798. * @throws ProcessIsolationException
  62799. */
  62800. private function saveConfigurationForChildProcess(): string
  62801. {
  62802. $path = tempnam(sys_get_temp_dir(), 'phpunit_');
  62803. if ($path === \false) {
  62804. throw new \PHPUnit\Framework\ProcessIsolationException();
  62805. }
  62806. if (!ConfigurationRegistry::saveTo($path)) {
  62807. throw new \PHPUnit\Framework\ProcessIsolationException();
  62808. }
  62809. return $path;
  62810. }
  62811. private function shouldErrorHandlerBeUsed(\PHPUnit\Framework\TestCase $test): bool
  62812. {
  62813. if (MetadataRegistry::parser()->forMethod($test::class, $test->name())->isWithoutErrorHandler()->isNotEmpty()) {
  62814. return \false;
  62815. }
  62816. return \true;
  62817. }
  62818. }
  62819. <?php
  62820. declare (strict_types=1);
  62821. /*
  62822. * This file is part of PHPUnit.
  62823. *
  62824. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62825. *
  62826. * For the full copyright and license information, please view the LICENSE
  62827. * file that was distributed with this source code.
  62828. */
  62829. namespace PHPUnit\Framework\TestSize;
  62830. /**
  62831. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62832. *
  62833. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62834. *
  62835. * @psalm-immutable
  62836. */
  62837. abstract class Known extends \PHPUnit\Framework\TestSize\TestSize
  62838. {
  62839. /**
  62840. * @psalm-assert-if-true Known $this
  62841. */
  62842. public function isKnown(): bool
  62843. {
  62844. return \true;
  62845. }
  62846. abstract public function isGreaterThan(self $other): bool;
  62847. }
  62848. <?php
  62849. declare (strict_types=1);
  62850. /*
  62851. * This file is part of PHPUnit.
  62852. *
  62853. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62854. *
  62855. * For the full copyright and license information, please view the LICENSE
  62856. * file that was distributed with this source code.
  62857. */
  62858. namespace PHPUnit\Framework\TestSize;
  62859. /**
  62860. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62861. *
  62862. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62863. *
  62864. * @psalm-immutable
  62865. */
  62866. final class Large extends \PHPUnit\Framework\TestSize\Known
  62867. {
  62868. /**
  62869. * @psalm-assert-if-true Large $this
  62870. */
  62871. public function isLarge(): bool
  62872. {
  62873. return \true;
  62874. }
  62875. public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
  62876. {
  62877. return !$other->isLarge();
  62878. }
  62879. public function asString(): string
  62880. {
  62881. return 'large';
  62882. }
  62883. }
  62884. <?php
  62885. declare (strict_types=1);
  62886. /*
  62887. * This file is part of PHPUnit.
  62888. *
  62889. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62890. *
  62891. * For the full copyright and license information, please view the LICENSE
  62892. * file that was distributed with this source code.
  62893. */
  62894. namespace PHPUnit\Framework\TestSize;
  62895. /**
  62896. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62897. *
  62898. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62899. *
  62900. * @psalm-immutable
  62901. */
  62902. final class Medium extends \PHPUnit\Framework\TestSize\Known
  62903. {
  62904. /**
  62905. * @psalm-assert-if-true Medium $this
  62906. */
  62907. public function isMedium(): bool
  62908. {
  62909. return \true;
  62910. }
  62911. public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
  62912. {
  62913. return $other->isSmall();
  62914. }
  62915. public function asString(): string
  62916. {
  62917. return 'medium';
  62918. }
  62919. }
  62920. <?php
  62921. declare (strict_types=1);
  62922. /*
  62923. * This file is part of PHPUnit.
  62924. *
  62925. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62926. *
  62927. * For the full copyright and license information, please view the LICENSE
  62928. * file that was distributed with this source code.
  62929. */
  62930. namespace PHPUnit\Framework\TestSize;
  62931. /**
  62932. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62933. *
  62934. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62935. *
  62936. * @psalm-immutable
  62937. */
  62938. final class Small extends \PHPUnit\Framework\TestSize\Known
  62939. {
  62940. /**
  62941. * @psalm-assert-if-true Small $this
  62942. */
  62943. public function isSmall(): bool
  62944. {
  62945. return \true;
  62946. }
  62947. public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
  62948. {
  62949. return \false;
  62950. }
  62951. public function asString(): string
  62952. {
  62953. return 'small';
  62954. }
  62955. }
  62956. <?php
  62957. declare (strict_types=1);
  62958. /*
  62959. * This file is part of PHPUnit.
  62960. *
  62961. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62962. *
  62963. * For the full copyright and license information, please view the LICENSE
  62964. * file that was distributed with this source code.
  62965. */
  62966. namespace PHPUnit\Framework\TestSize;
  62967. /**
  62968. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  62969. *
  62970. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  62971. *
  62972. * @psalm-immutable
  62973. */
  62974. abstract class TestSize
  62975. {
  62976. public static function unknown(): self
  62977. {
  62978. return new \PHPUnit\Framework\TestSize\Unknown();
  62979. }
  62980. public static function small(): self
  62981. {
  62982. return new \PHPUnit\Framework\TestSize\Small();
  62983. }
  62984. public static function medium(): self
  62985. {
  62986. return new \PHPUnit\Framework\TestSize\Medium();
  62987. }
  62988. public static function large(): self
  62989. {
  62990. return new \PHPUnit\Framework\TestSize\Large();
  62991. }
  62992. /**
  62993. * @psalm-assert-if-true Known $this
  62994. */
  62995. public function isKnown(): bool
  62996. {
  62997. return \false;
  62998. }
  62999. /**
  63000. * @psalm-assert-if-true Unknown $this
  63001. */
  63002. public function isUnknown(): bool
  63003. {
  63004. return \false;
  63005. }
  63006. /**
  63007. * @psalm-assert-if-true Small $this
  63008. */
  63009. public function isSmall(): bool
  63010. {
  63011. return \false;
  63012. }
  63013. /**
  63014. * @psalm-assert-if-true Medium $this
  63015. */
  63016. public function isMedium(): bool
  63017. {
  63018. return \false;
  63019. }
  63020. /**
  63021. * @psalm-assert-if-true Large $this
  63022. */
  63023. public function isLarge(): bool
  63024. {
  63025. return \false;
  63026. }
  63027. abstract public function asString(): string;
  63028. }
  63029. <?php
  63030. declare (strict_types=1);
  63031. /*
  63032. * This file is part of PHPUnit.
  63033. *
  63034. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63035. *
  63036. * For the full copyright and license information, please view the LICENSE
  63037. * file that was distributed with this source code.
  63038. */
  63039. namespace PHPUnit\Framework\TestSize;
  63040. /**
  63041. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63042. *
  63043. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63044. *
  63045. * @psalm-immutable
  63046. */
  63047. final class Unknown extends \PHPUnit\Framework\TestSize\TestSize
  63048. {
  63049. /**
  63050. * @psalm-assert-if-true Unknown $this
  63051. */
  63052. public function isUnknown(): bool
  63053. {
  63054. return \true;
  63055. }
  63056. public function asString(): string
  63057. {
  63058. return 'unknown';
  63059. }
  63060. }
  63061. <?php
  63062. declare (strict_types=1);
  63063. /*
  63064. * This file is part of PHPUnit.
  63065. *
  63066. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63067. *
  63068. * For the full copyright and license information, please view the LICENSE
  63069. * file that was distributed with this source code.
  63070. */
  63071. namespace PHPUnit\Framework\TestStatus;
  63072. /**
  63073. * @psalm-immutable
  63074. *
  63075. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63076. *
  63077. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63078. */
  63079. final class Deprecation extends \PHPUnit\Framework\TestStatus\Known
  63080. {
  63081. /**
  63082. * @psalm-assert-if-true Deprecation $this
  63083. */
  63084. public function isDeprecation(): bool
  63085. {
  63086. return \true;
  63087. }
  63088. public function asInt(): int
  63089. {
  63090. return 4;
  63091. }
  63092. public function asString(): string
  63093. {
  63094. return 'deprecation';
  63095. }
  63096. }
  63097. <?php
  63098. declare (strict_types=1);
  63099. /*
  63100. * This file is part of PHPUnit.
  63101. *
  63102. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63103. *
  63104. * For the full copyright and license information, please view the LICENSE
  63105. * file that was distributed with this source code.
  63106. */
  63107. namespace PHPUnit\Framework\TestStatus;
  63108. /**
  63109. * @psalm-immutable
  63110. *
  63111. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63112. *
  63113. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63114. */
  63115. final class Error extends \PHPUnit\Framework\TestStatus\Known
  63116. {
  63117. /**
  63118. * @psalm-assert-if-true Error $this
  63119. */
  63120. public function isError(): bool
  63121. {
  63122. return \true;
  63123. }
  63124. public function asInt(): int
  63125. {
  63126. return 8;
  63127. }
  63128. public function asString(): string
  63129. {
  63130. return 'error';
  63131. }
  63132. }
  63133. <?php
  63134. declare (strict_types=1);
  63135. /*
  63136. * This file is part of PHPUnit.
  63137. *
  63138. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63139. *
  63140. * For the full copyright and license information, please view the LICENSE
  63141. * file that was distributed with this source code.
  63142. */
  63143. namespace PHPUnit\Framework\TestStatus;
  63144. /**
  63145. * @psalm-immutable
  63146. *
  63147. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63148. *
  63149. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63150. */
  63151. final class Failure extends \PHPUnit\Framework\TestStatus\Known
  63152. {
  63153. /**
  63154. * @psalm-assert-if-true Failure $this
  63155. */
  63156. public function isFailure(): bool
  63157. {
  63158. return \true;
  63159. }
  63160. public function asInt(): int
  63161. {
  63162. return 7;
  63163. }
  63164. public function asString(): string
  63165. {
  63166. return 'failure';
  63167. }
  63168. }
  63169. <?php
  63170. declare (strict_types=1);
  63171. /*
  63172. * This file is part of PHPUnit.
  63173. *
  63174. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63175. *
  63176. * For the full copyright and license information, please view the LICENSE
  63177. * file that was distributed with this source code.
  63178. */
  63179. namespace PHPUnit\Framework\TestStatus;
  63180. /**
  63181. * @psalm-immutable
  63182. *
  63183. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63184. *
  63185. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63186. */
  63187. final class Incomplete extends \PHPUnit\Framework\TestStatus\Known
  63188. {
  63189. /**
  63190. * @psalm-assert-if-true Incomplete $this
  63191. */
  63192. public function isIncomplete(): bool
  63193. {
  63194. return \true;
  63195. }
  63196. public function asInt(): int
  63197. {
  63198. return 2;
  63199. }
  63200. public function asString(): string
  63201. {
  63202. return 'incomplete';
  63203. }
  63204. }
  63205. <?php
  63206. declare (strict_types=1);
  63207. /*
  63208. * This file is part of PHPUnit.
  63209. *
  63210. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63211. *
  63212. * For the full copyright and license information, please view the LICENSE
  63213. * file that was distributed with this source code.
  63214. */
  63215. namespace PHPUnit\Framework\TestStatus;
  63216. /**
  63217. * @psalm-immutable
  63218. *
  63219. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63220. *
  63221. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63222. */
  63223. abstract class Known extends \PHPUnit\Framework\TestStatus\TestStatus
  63224. {
  63225. /**
  63226. * @psalm-assert-if-true Known $this
  63227. */
  63228. public function isKnown(): bool
  63229. {
  63230. return \true;
  63231. }
  63232. }
  63233. <?php
  63234. declare (strict_types=1);
  63235. /*
  63236. * This file is part of PHPUnit.
  63237. *
  63238. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63239. *
  63240. * For the full copyright and license information, please view the LICENSE
  63241. * file that was distributed with this source code.
  63242. */
  63243. namespace PHPUnit\Framework\TestStatus;
  63244. /**
  63245. * @psalm-immutable
  63246. *
  63247. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63248. *
  63249. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63250. */
  63251. final class Notice extends \PHPUnit\Framework\TestStatus\Known
  63252. {
  63253. /**
  63254. * @psalm-assert-if-true Notice $this
  63255. */
  63256. public function isNotice(): bool
  63257. {
  63258. return \true;
  63259. }
  63260. public function asInt(): int
  63261. {
  63262. return 3;
  63263. }
  63264. public function asString(): string
  63265. {
  63266. return 'notice';
  63267. }
  63268. }
  63269. <?php
  63270. declare (strict_types=1);
  63271. /*
  63272. * This file is part of PHPUnit.
  63273. *
  63274. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63275. *
  63276. * For the full copyright and license information, please view the LICENSE
  63277. * file that was distributed with this source code.
  63278. */
  63279. namespace PHPUnit\Framework\TestStatus;
  63280. /**
  63281. * @psalm-immutable
  63282. *
  63283. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63284. *
  63285. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63286. */
  63287. final class Risky extends \PHPUnit\Framework\TestStatus\Known
  63288. {
  63289. /**
  63290. * @psalm-assert-if-true Risky $this
  63291. */
  63292. public function isRisky(): bool
  63293. {
  63294. return \true;
  63295. }
  63296. public function asInt(): int
  63297. {
  63298. return 5;
  63299. }
  63300. public function asString(): string
  63301. {
  63302. return 'risky';
  63303. }
  63304. }
  63305. <?php
  63306. declare (strict_types=1);
  63307. /*
  63308. * This file is part of PHPUnit.
  63309. *
  63310. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63311. *
  63312. * For the full copyright and license information, please view the LICENSE
  63313. * file that was distributed with this source code.
  63314. */
  63315. namespace PHPUnit\Framework\TestStatus;
  63316. /**
  63317. * @psalm-immutable
  63318. *
  63319. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63320. *
  63321. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63322. */
  63323. final class Skipped extends \PHPUnit\Framework\TestStatus\Known
  63324. {
  63325. /**
  63326. * @psalm-assert-if-true Skipped $this
  63327. */
  63328. public function isSkipped(): bool
  63329. {
  63330. return \true;
  63331. }
  63332. public function asInt(): int
  63333. {
  63334. return 1;
  63335. }
  63336. public function asString(): string
  63337. {
  63338. return 'skipped';
  63339. }
  63340. }
  63341. <?php
  63342. declare (strict_types=1);
  63343. /*
  63344. * This file is part of PHPUnit.
  63345. *
  63346. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63347. *
  63348. * For the full copyright and license information, please view the LICENSE
  63349. * file that was distributed with this source code.
  63350. */
  63351. namespace PHPUnit\Framework\TestStatus;
  63352. /**
  63353. * @psalm-immutable
  63354. *
  63355. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63356. *
  63357. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63358. */
  63359. final class Success extends \PHPUnit\Framework\TestStatus\Known
  63360. {
  63361. /**
  63362. * @psalm-assert-if-true Success $this
  63363. */
  63364. public function isSuccess(): bool
  63365. {
  63366. return \true;
  63367. }
  63368. public function asInt(): int
  63369. {
  63370. return 0;
  63371. }
  63372. public function asString(): string
  63373. {
  63374. return 'success';
  63375. }
  63376. }
  63377. <?php
  63378. declare (strict_types=1);
  63379. /*
  63380. * This file is part of PHPUnit.
  63381. *
  63382. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63383. *
  63384. * For the full copyright and license information, please view the LICENSE
  63385. * file that was distributed with this source code.
  63386. */
  63387. namespace PHPUnit\Framework\TestStatus;
  63388. /**
  63389. * @psalm-immutable
  63390. *
  63391. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63392. *
  63393. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63394. */
  63395. abstract class TestStatus
  63396. {
  63397. private readonly string $message;
  63398. public static function from(int $status): self
  63399. {
  63400. return match ($status) {
  63401. 0 => self::success(),
  63402. 1 => self::skipped(),
  63403. 2 => self::incomplete(),
  63404. 3 => self::notice(),
  63405. 4 => self::deprecation(),
  63406. 5 => self::risky(),
  63407. 6 => self::warning(),
  63408. 7 => self::failure(),
  63409. 8 => self::error(),
  63410. default => self::unknown(),
  63411. };
  63412. }
  63413. public static function unknown(): self
  63414. {
  63415. return new \PHPUnit\Framework\TestStatus\Unknown();
  63416. }
  63417. public static function success(): self
  63418. {
  63419. return new \PHPUnit\Framework\TestStatus\Success();
  63420. }
  63421. public static function skipped(string $message = ''): self
  63422. {
  63423. return new \PHPUnit\Framework\TestStatus\Skipped($message);
  63424. }
  63425. public static function incomplete(string $message = ''): self
  63426. {
  63427. return new \PHPUnit\Framework\TestStatus\Incomplete($message);
  63428. }
  63429. public static function notice(string $message = ''): self
  63430. {
  63431. return new \PHPUnit\Framework\TestStatus\Notice($message);
  63432. }
  63433. public static function deprecation(string $message = ''): self
  63434. {
  63435. return new \PHPUnit\Framework\TestStatus\Deprecation($message);
  63436. }
  63437. public static function failure(string $message = ''): self
  63438. {
  63439. return new \PHPUnit\Framework\TestStatus\Failure($message);
  63440. }
  63441. public static function error(string $message = ''): self
  63442. {
  63443. return new \PHPUnit\Framework\TestStatus\Error($message);
  63444. }
  63445. public static function warning(string $message = ''): self
  63446. {
  63447. return new \PHPUnit\Framework\TestStatus\Warning($message);
  63448. }
  63449. public static function risky(string $message = ''): self
  63450. {
  63451. return new \PHPUnit\Framework\TestStatus\Risky($message);
  63452. }
  63453. private function __construct(string $message = '')
  63454. {
  63455. $this->message = $message;
  63456. }
  63457. /**
  63458. * @psalm-assert-if-true Known $this
  63459. */
  63460. public function isKnown(): bool
  63461. {
  63462. return \false;
  63463. }
  63464. /**
  63465. * @psalm-assert-if-true Unknown $this
  63466. */
  63467. public function isUnknown(): bool
  63468. {
  63469. return \false;
  63470. }
  63471. /**
  63472. * @psalm-assert-if-true Success $this
  63473. */
  63474. public function isSuccess(): bool
  63475. {
  63476. return \false;
  63477. }
  63478. /**
  63479. * @psalm-assert-if-true Skipped $this
  63480. */
  63481. public function isSkipped(): bool
  63482. {
  63483. return \false;
  63484. }
  63485. /**
  63486. * @psalm-assert-if-true Incomplete $this
  63487. */
  63488. public function isIncomplete(): bool
  63489. {
  63490. return \false;
  63491. }
  63492. /**
  63493. * @psalm-assert-if-true Notice $this
  63494. */
  63495. public function isNotice(): bool
  63496. {
  63497. return \false;
  63498. }
  63499. /**
  63500. * @psalm-assert-if-true Deprecation $this
  63501. */
  63502. public function isDeprecation(): bool
  63503. {
  63504. return \false;
  63505. }
  63506. /**
  63507. * @psalm-assert-if-true Failure $this
  63508. */
  63509. public function isFailure(): bool
  63510. {
  63511. return \false;
  63512. }
  63513. /**
  63514. * @psalm-assert-if-true Error $this
  63515. */
  63516. public function isError(): bool
  63517. {
  63518. return \false;
  63519. }
  63520. /**
  63521. * @psalm-assert-if-true Warning $this
  63522. */
  63523. public function isWarning(): bool
  63524. {
  63525. return \false;
  63526. }
  63527. /**
  63528. * @psalm-assert-if-true Risky $this
  63529. */
  63530. public function isRisky(): bool
  63531. {
  63532. return \false;
  63533. }
  63534. public function message(): string
  63535. {
  63536. return $this->message;
  63537. }
  63538. public function isMoreImportantThan(self $other): bool
  63539. {
  63540. return $this->asInt() > $other->asInt();
  63541. }
  63542. abstract public function asInt(): int;
  63543. abstract public function asString(): string;
  63544. }
  63545. <?php
  63546. declare (strict_types=1);
  63547. /*
  63548. * This file is part of PHPUnit.
  63549. *
  63550. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63551. *
  63552. * For the full copyright and license information, please view the LICENSE
  63553. * file that was distributed with this source code.
  63554. */
  63555. namespace PHPUnit\Framework\TestStatus;
  63556. /**
  63557. * @psalm-immutable
  63558. *
  63559. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63560. *
  63561. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63562. */
  63563. final class Unknown extends \PHPUnit\Framework\TestStatus\TestStatus
  63564. {
  63565. /**
  63566. * @psalm-assert-if-true Unknown $this
  63567. */
  63568. public function isUnknown(): bool
  63569. {
  63570. return \true;
  63571. }
  63572. public function asInt(): int
  63573. {
  63574. return -1;
  63575. }
  63576. public function asString(): string
  63577. {
  63578. return 'unknown';
  63579. }
  63580. }
  63581. <?php
  63582. declare (strict_types=1);
  63583. /*
  63584. * This file is part of PHPUnit.
  63585. *
  63586. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63587. *
  63588. * For the full copyright and license information, please view the LICENSE
  63589. * file that was distributed with this source code.
  63590. */
  63591. namespace PHPUnit\Framework\TestStatus;
  63592. /**
  63593. * @psalm-immutable
  63594. *
  63595. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63596. *
  63597. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63598. */
  63599. final class Warning extends \PHPUnit\Framework\TestStatus\Known
  63600. {
  63601. /**
  63602. * @psalm-assert-if-true Warning $this
  63603. */
  63604. public function isWarning(): bool
  63605. {
  63606. return \true;
  63607. }
  63608. public function asInt(): int
  63609. {
  63610. return 6;
  63611. }
  63612. public function asString(): string
  63613. {
  63614. return 'warning';
  63615. }
  63616. }
  63617. <?php
  63618. declare (strict_types=1);
  63619. /*
  63620. * This file is part of PHPUnit.
  63621. *
  63622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63623. *
  63624. * For the full copyright and license information, please view the LICENSE
  63625. * file that was distributed with this source code.
  63626. */
  63627. namespace PHPUnit\Framework;
  63628. use const PHP_EOL;
  63629. use function array_keys;
  63630. use function array_map;
  63631. use function array_pop;
  63632. use function array_reverse;
  63633. use function assert;
  63634. use function call_user_func;
  63635. use function class_exists;
  63636. use function count;
  63637. use function implode;
  63638. use function is_callable;
  63639. use function is_file;
  63640. use function is_subclass_of;
  63641. use function sprintf;
  63642. use function str_ends_with;
  63643. use function str_starts_with;
  63644. use function trim;
  63645. use Iterator;
  63646. use IteratorAggregate;
  63647. use PHPUnit\Event;
  63648. use PHPUnit\Event\Code\TestMethod;
  63649. use PHPUnit\Event\NoPreviousThrowableException;
  63650. use PHPUnit\Metadata\Api\Dependencies;
  63651. use PHPUnit\Metadata\Api\Groups;
  63652. use PHPUnit\Metadata\Api\HookMethods;
  63653. use PHPUnit\Metadata\Api\Requirements;
  63654. use PHPUnit\Metadata\MetadataCollection;
  63655. use PHPUnit\Runner\Exception as RunnerException;
  63656. use PHPUnit\Runner\Filter\Factory;
  63657. use PHPUnit\Runner\PhptTestCase;
  63658. use PHPUnit\Runner\TestSuiteLoader;
  63659. use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
  63660. use PHPUnit\Util\Filter;
  63661. use PHPUnit\Util\Reflection;
  63662. use PHPUnit\Util\Test as TestUtil;
  63663. use ReflectionClass;
  63664. use ReflectionMethod;
  63665. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
  63666. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
  63667. use Throwable;
  63668. /**
  63669. * @template-implements IteratorAggregate<int, Test>
  63670. *
  63671. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  63672. *
  63673. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  63674. */
  63675. class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \PHPUnit\Framework\SelfDescribing, \PHPUnit\Framework\Test
  63676. {
  63677. /**
  63678. * @psalm-var non-empty-string
  63679. */
  63680. private string $name;
  63681. /**
  63682. * @psalm-var array<string,list<Test>>
  63683. */
  63684. private array $groups = [];
  63685. /**
  63686. * @psalm-var ?list<ExecutionOrderDependency>
  63687. */
  63688. private ?array $requiredTests = null;
  63689. /**
  63690. * @psalm-var list<Test>
  63691. */
  63692. private array $tests = [];
  63693. /**
  63694. * @psalm-var ?list<ExecutionOrderDependency>
  63695. */
  63696. private ?array $providedTests = null;
  63697. private ?Factory $iteratorFilter = null;
  63698. private bool $wasRun = \false;
  63699. /**
  63700. * @psalm-param non-empty-string $name
  63701. */
  63702. public static function empty(string $name): static
  63703. {
  63704. return new static($name);
  63705. }
  63706. /**
  63707. * @psalm-param class-string $className
  63708. */
  63709. public static function fromClassName(string $className): static
  63710. {
  63711. assert(class_exists($className));
  63712. $class = new ReflectionClass($className);
  63713. return static::fromClassReflector($class);
  63714. }
  63715. public static function fromClassReflector(ReflectionClass $class): static
  63716. {
  63717. $testSuite = new static($class->getName());
  63718. $constructor = $class->getConstructor();
  63719. if ($constructor !== null && !$constructor->isPublic()) {
  63720. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Class "%s" has no public constructor.', $class->getName()));
  63721. return $testSuite;
  63722. }
  63723. foreach (Reflection::publicMethodsInTestClass($class) as $method) {
  63724. if ($method->getDeclaringClass()->getName() === \PHPUnit\Framework\Assert::class) {
  63725. continue;
  63726. }
  63727. if ($method->getDeclaringClass()->getName() === \PHPUnit\Framework\TestCase::class) {
  63728. continue;
  63729. }
  63730. if (!TestUtil::isTestMethod($method)) {
  63731. continue;
  63732. }
  63733. $testSuite->addTestMethod($class, $method);
  63734. }
  63735. if ($testSuite->isEmpty()) {
  63736. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('No tests found in class "%s".', $class->getName()));
  63737. }
  63738. return $testSuite;
  63739. }
  63740. /**
  63741. * @psalm-param non-empty-string $name
  63742. */
  63743. final private function __construct(string $name)
  63744. {
  63745. $this->name = $name;
  63746. }
  63747. /**
  63748. * Returns a string representation of the test suite.
  63749. */
  63750. public function toString(): string
  63751. {
  63752. return $this->name();
  63753. }
  63754. /**
  63755. * Adds a test to the suite.
  63756. */
  63757. public function addTest(\PHPUnit\Framework\Test $test, array $groups = []): void
  63758. {
  63759. $class = new ReflectionClass($test);
  63760. if ($class->isAbstract()) {
  63761. return;
  63762. }
  63763. $this->tests[] = $test;
  63764. $this->clearCaches();
  63765. if ($test instanceof self && empty($groups)) {
  63766. $groups = $test->groups();
  63767. }
  63768. if ($this->containsOnlyVirtualGroups($groups)) {
  63769. $groups[] = 'default';
  63770. }
  63771. foreach ($groups as $group) {
  63772. if (!isset($this->groups[$group])) {
  63773. $this->groups[$group] = [$test];
  63774. } else {
  63775. $this->groups[$group][] = $test;
  63776. }
  63777. }
  63778. if ($test instanceof \PHPUnit\Framework\TestCase) {
  63779. $test->setGroups($groups);
  63780. }
  63781. }
  63782. /**
  63783. * Adds the tests from the given class to the suite.
  63784. *
  63785. * @throws Exception
  63786. */
  63787. public function addTestSuite(ReflectionClass $testClass): void
  63788. {
  63789. if ($testClass->isAbstract()) {
  63790. throw new \PHPUnit\Framework\Exception(sprintf('Class %s is abstract', $testClass->getName()));
  63791. }
  63792. if (!$testClass->isSubclassOf(\PHPUnit\Framework\TestCase::class)) {
  63793. throw new \PHPUnit\Framework\Exception(sprintf('Class %s is not a subclass of %s', $testClass->getName(), \PHPUnit\Framework\TestCase::class));
  63794. }
  63795. $this->addTest(self::fromClassReflector($testClass));
  63796. }
  63797. /**
  63798. * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
  63799. * as well as the separate import statements for the user's convenience.
  63800. *
  63801. * If the named file cannot be read or there are no new tests that can be
  63802. * added, a <code>PHPUnit\Framework\WarningTestCase</code> will be created instead,
  63803. * leaving the current test run untouched.
  63804. *
  63805. * @throws Exception
  63806. */
  63807. public function addTestFile(string $filename): void
  63808. {
  63809. try {
  63810. if (str_ends_with($filename, '.phpt') && is_file($filename)) {
  63811. $this->addTest(new PhptTestCase($filename));
  63812. } else {
  63813. $this->addTestSuite((new TestSuiteLoader())->load($filename));
  63814. }
  63815. } catch (RunnerException $e) {
  63816. Event\Facade::emitter()->testRunnerTriggeredWarning($e->getMessage());
  63817. }
  63818. }
  63819. /**
  63820. * Wrapper for addTestFile() that adds multiple test files.
  63821. *
  63822. * @throws Exception
  63823. */
  63824. public function addTestFiles(iterable $fileNames): void
  63825. {
  63826. foreach ($fileNames as $filename) {
  63827. $this->addTestFile((string) $filename);
  63828. }
  63829. }
  63830. /**
  63831. * Counts the number of test cases that will be run by this test.
  63832. */
  63833. public function count(): int
  63834. {
  63835. $numTests = 0;
  63836. foreach ($this as $test) {
  63837. $numTests += count($test);
  63838. }
  63839. return $numTests;
  63840. }
  63841. public function isEmpty(): bool
  63842. {
  63843. foreach ($this as $test) {
  63844. if (count($test) !== 0) {
  63845. return \false;
  63846. }
  63847. }
  63848. return \true;
  63849. }
  63850. /**
  63851. * @psalm-return non-empty-string
  63852. */
  63853. public function name(): string
  63854. {
  63855. return $this->name;
  63856. }
  63857. /**
  63858. * Returns the test groups of the suite.
  63859. *
  63860. * @psalm-return list<string>
  63861. */
  63862. public function groups(): array
  63863. {
  63864. return array_map('strval', array_keys($this->groups));
  63865. }
  63866. public function groupDetails(): array
  63867. {
  63868. return $this->groups;
  63869. }
  63870. /**
  63871. * @throws CodeCoverageException
  63872. * @throws Event\RuntimeException
  63873. * @throws Exception
  63874. * @throws InvalidArgumentException
  63875. * @throws NoPreviousThrowableException
  63876. * @throws UnintentionallyCoveredCodeException
  63877. */
  63878. public function run(): void
  63879. {
  63880. if ($this->wasRun) {
  63881. // @codeCoverageIgnoreStart
  63882. throw new \PHPUnit\Framework\Exception('The tests aggregated by this TestSuite were already run');
  63883. // @codeCoverageIgnoreEnd
  63884. }
  63885. $this->wasRun = \true;
  63886. if ($this->isEmpty()) {
  63887. return;
  63888. }
  63889. $emitter = Event\Facade::emitter();
  63890. $testSuiteValueObjectForEvents = Event\TestSuite\TestSuiteBuilder::from($this);
  63891. $emitter->testSuiteStarted($testSuiteValueObjectForEvents);
  63892. if (!$this->invokeMethodsBeforeFirstTest($emitter, $testSuiteValueObjectForEvents)) {
  63893. return;
  63894. }
  63895. /** @psalm-var list<Test> $tests */
  63896. $tests = [];
  63897. foreach ($this as $test) {
  63898. $tests[] = $test;
  63899. }
  63900. $tests = array_reverse($tests);
  63901. $this->tests = [];
  63902. $this->groups = [];
  63903. while (($test = array_pop($tests)) !== null) {
  63904. if (TestResultFacade::shouldStop()) {
  63905. $emitter->testRunnerExecutionAborted();
  63906. break;
  63907. }
  63908. $test->run();
  63909. }
  63910. $this->invokeMethodsAfterLastTest($emitter);
  63911. $emitter->testSuiteFinished($testSuiteValueObjectForEvents);
  63912. }
  63913. /**
  63914. * Returns the tests as an enumeration.
  63915. *
  63916. * @psalm-return list<Test>
  63917. */
  63918. public function tests(): array
  63919. {
  63920. return $this->tests;
  63921. }
  63922. /**
  63923. * Set tests of the test suite.
  63924. *
  63925. * @psalm-param list<Test> $tests
  63926. */
  63927. public function setTests(array $tests): void
  63928. {
  63929. $this->tests = $tests;
  63930. }
  63931. /**
  63932. * Mark the test suite as skipped.
  63933. *
  63934. * @throws SkippedTestSuiteError
  63935. */
  63936. public function markTestSuiteSkipped(string $message = ''): never
  63937. {
  63938. throw new \PHPUnit\Framework\SkippedTestSuiteError($message);
  63939. }
  63940. /**
  63941. * Returns an iterator for this test suite.
  63942. */
  63943. public function getIterator(): Iterator
  63944. {
  63945. $iterator = new \PHPUnit\Framework\TestSuiteIterator($this);
  63946. if ($this->iteratorFilter !== null) {
  63947. $iterator = $this->iteratorFilter->factory($iterator, $this);
  63948. }
  63949. return $iterator;
  63950. }
  63951. public function injectFilter(Factory $filter): void
  63952. {
  63953. $this->iteratorFilter = $filter;
  63954. foreach ($this as $test) {
  63955. if ($test instanceof self) {
  63956. $test->injectFilter($filter);
  63957. }
  63958. }
  63959. }
  63960. /**
  63961. * @psalm-return list<ExecutionOrderDependency>
  63962. */
  63963. public function provides(): array
  63964. {
  63965. if ($this->providedTests === null) {
  63966. $this->providedTests = [];
  63967. if (is_callable($this->sortId(), \true)) {
  63968. $this->providedTests[] = new \PHPUnit\Framework\ExecutionOrderDependency($this->sortId());
  63969. }
  63970. foreach ($this->tests as $test) {
  63971. if (!$test instanceof \PHPUnit\Framework\Reorderable) {
  63972. continue;
  63973. }
  63974. $this->providedTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique($this->providedTests, $test->provides());
  63975. }
  63976. }
  63977. return $this->providedTests;
  63978. }
  63979. /**
  63980. * @psalm-return list<ExecutionOrderDependency>
  63981. */
  63982. public function requires(): array
  63983. {
  63984. if ($this->requiredTests === null) {
  63985. $this->requiredTests = [];
  63986. foreach ($this->tests as $test) {
  63987. if (!$test instanceof \PHPUnit\Framework\Reorderable) {
  63988. continue;
  63989. }
  63990. $this->requiredTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique(\PHPUnit\Framework\ExecutionOrderDependency::filterInvalid($this->requiredTests), $test->requires());
  63991. }
  63992. $this->requiredTests = \PHPUnit\Framework\ExecutionOrderDependency::diff($this->requiredTests, $this->provides());
  63993. }
  63994. return $this->requiredTests;
  63995. }
  63996. public function sortId(): string
  63997. {
  63998. return $this->name() . '::class';
  63999. }
  64000. /**
  64001. * @psalm-assert-if-true class-string $this->name
  64002. */
  64003. public function isForTestClass(): bool
  64004. {
  64005. return class_exists($this->name, \false) && is_subclass_of($this->name, \PHPUnit\Framework\TestCase::class);
  64006. }
  64007. /**
  64008. * @throws Event\TestData\MoreThanOneDataSetFromDataProviderException
  64009. * @throws Exception
  64010. */
  64011. protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method): void
  64012. {
  64013. $className = $class->getName();
  64014. $methodName = $method->getName();
  64015. assert(!empty($methodName));
  64016. try {
  64017. $test = (new \PHPUnit\Framework\TestBuilder())->build($class, $methodName);
  64018. } catch (\PHPUnit\Framework\InvalidDataProviderException $e) {
  64019. Event\Facade::emitter()->testTriggeredPhpunitError(new TestMethod($className, $methodName, $class->getFileName(), $method->getStartLine(), Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataCollection::fromArray([]), Event\TestData\TestDataCollection::fromArray([])), sprintf("The data provider specified for %s::%s is invalid\n%s", $className, $methodName, $this->throwableToString($e)));
  64020. return;
  64021. }
  64022. if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof \PHPUnit\Framework\DataProviderTestSuite) {
  64023. $test->setDependencies(Dependencies::dependencies($class->getName(), $methodName));
  64024. }
  64025. $this->addTest($test, (new Groups())->groups($class->getName(), $methodName));
  64026. }
  64027. private function clearCaches(): void
  64028. {
  64029. $this->providedTests = null;
  64030. $this->requiredTests = null;
  64031. }
  64032. private function containsOnlyVirtualGroups(array $groups): bool
  64033. {
  64034. foreach ($groups as $group) {
  64035. if (!str_starts_with($group, '__phpunit_')) {
  64036. return \false;
  64037. }
  64038. }
  64039. return \true;
  64040. }
  64041. private function methodDoesNotExistOrIsDeclaredInTestCase(string $methodName): bool
  64042. {
  64043. $reflector = new ReflectionClass($this->name);
  64044. return !$reflector->hasMethod($methodName) || $reflector->getMethod($methodName)->getDeclaringClass()->getName() === \PHPUnit\Framework\TestCase::class;
  64045. }
  64046. /**
  64047. * @throws Exception
  64048. */
  64049. private function throwableToString(Throwable $t): string
  64050. {
  64051. $message = $t->getMessage();
  64052. if (empty(trim($message))) {
  64053. $message = '<no message>';
  64054. }
  64055. if ($t instanceof \PHPUnit\Framework\InvalidDataProviderException) {
  64056. return sprintf("%s\n%s", $message, Filter::getFilteredStacktrace($t));
  64057. }
  64058. return sprintf("%s: %s\n%s", $t::class, $message, Filter::getFilteredStacktrace($t));
  64059. }
  64060. /**
  64061. * @throws Exception
  64062. * @throws NoPreviousThrowableException
  64063. */
  64064. private function invokeMethodsBeforeFirstTest(Event\Emitter $emitter, Event\TestSuite\TestSuite $testSuiteValueObjectForEvents): bool
  64065. {
  64066. if (!$this->isForTestClass()) {
  64067. return \true;
  64068. }
  64069. $methodsCalledBeforeFirstTest = [];
  64070. $beforeClassMethods = (new HookMethods())->hookMethods($this->name)['beforeClass'];
  64071. try {
  64072. foreach ($beforeClassMethods as $beforeClassMethod) {
  64073. if ($this->methodDoesNotExistOrIsDeclaredInTestCase($beforeClassMethod)) {
  64074. continue;
  64075. }
  64076. if ($missingRequirements = (new Requirements())->requirementsNotSatisfiedFor($this->name, $beforeClassMethod)) {
  64077. $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
  64078. }
  64079. $methodCalledBeforeFirstTest = new Event\Code\ClassMethod($this->name, $beforeClassMethod);
  64080. $emitter->testBeforeFirstTestMethodCalled($this->name, $methodCalledBeforeFirstTest);
  64081. $methodsCalledBeforeFirstTest[] = $methodCalledBeforeFirstTest;
  64082. call_user_func([$this->name, $beforeClassMethod]);
  64083. }
  64084. } catch (\PHPUnit\Framework\SkippedTest|\PHPUnit\Framework\SkippedTestSuiteError $e) {
  64085. $emitter->testSuiteSkipped($testSuiteValueObjectForEvents, $e->getMessage());
  64086. return \false;
  64087. } catch (Throwable $t) {
  64088. assert(isset($methodCalledBeforeFirstTest));
  64089. $emitter->testBeforeFirstTestMethodErrored($this->name, $methodCalledBeforeFirstTest, Event\Code\ThrowableBuilder::from($t));
  64090. if (!empty($methodsCalledBeforeFirstTest)) {
  64091. $emitter->testBeforeFirstTestMethodFinished($this->name, ...$methodsCalledBeforeFirstTest);
  64092. }
  64093. return \false;
  64094. }
  64095. if (!empty($methodsCalledBeforeFirstTest)) {
  64096. $emitter->testBeforeFirstTestMethodFinished($this->name, ...$methodsCalledBeforeFirstTest);
  64097. }
  64098. return \true;
  64099. }
  64100. private function invokeMethodsAfterLastTest(Event\Emitter $emitter): void
  64101. {
  64102. if (!$this->isForTestClass()) {
  64103. return;
  64104. }
  64105. $methodsCalledAfterLastTest = [];
  64106. $afterClassMethods = (new HookMethods())->hookMethods($this->name)['afterClass'];
  64107. foreach ($afterClassMethods as $afterClassMethod) {
  64108. if ($this->methodDoesNotExistOrIsDeclaredInTestCase($afterClassMethod)) {
  64109. continue;
  64110. }
  64111. try {
  64112. call_user_func([$this->name, $afterClassMethod]);
  64113. $methodCalledAfterLastTest = new Event\Code\ClassMethod($this->name, $afterClassMethod);
  64114. $emitter->testAfterLastTestMethodCalled($this->name, $methodCalledAfterLastTest);
  64115. $methodsCalledAfterLastTest[] = $methodCalledAfterLastTest;
  64116. } catch (Throwable) {
  64117. // @todo
  64118. }
  64119. }
  64120. if (!empty($methodsCalledAfterLastTest)) {
  64121. $emitter->testAfterLastTestMethodFinished($this->name, ...$methodsCalledAfterLastTest);
  64122. }
  64123. }
  64124. }
  64125. <?php
  64126. declare (strict_types=1);
  64127. /*
  64128. * This file is part of PHPUnit.
  64129. *
  64130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64131. *
  64132. * For the full copyright and license information, please view the LICENSE
  64133. * file that was distributed with this source code.
  64134. */
  64135. namespace PHPUnit\Framework;
  64136. use function assert;
  64137. use function count;
  64138. use RecursiveIterator;
  64139. /**
  64140. * @template-implements RecursiveIterator<int, Test>
  64141. *
  64142. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64143. *
  64144. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64145. */
  64146. final class TestSuiteIterator implements RecursiveIterator
  64147. {
  64148. private int $position = 0;
  64149. /**
  64150. * @psalm-var list<Test>
  64151. */
  64152. private readonly array $tests;
  64153. public function __construct(\PHPUnit\Framework\TestSuite $testSuite)
  64154. {
  64155. $this->tests = $testSuite->tests();
  64156. }
  64157. public function rewind(): void
  64158. {
  64159. $this->position = 0;
  64160. }
  64161. public function valid(): bool
  64162. {
  64163. return $this->position < count($this->tests);
  64164. }
  64165. public function key(): int
  64166. {
  64167. return $this->position;
  64168. }
  64169. public function current(): \PHPUnit\Framework\Test
  64170. {
  64171. return $this->tests[$this->position];
  64172. }
  64173. public function next(): void
  64174. {
  64175. $this->position++;
  64176. }
  64177. /**
  64178. * @throws NoChildTestSuiteException
  64179. */
  64180. public function getChildren(): self
  64181. {
  64182. if (!$this->hasChildren()) {
  64183. throw new \PHPUnit\Framework\NoChildTestSuiteException('The current item is not a TestSuite instance and therefore does not have any children.');
  64184. }
  64185. $current = $this->current();
  64186. assert($current instanceof \PHPUnit\Framework\TestSuite);
  64187. return new self($current);
  64188. }
  64189. public function hasChildren(): bool
  64190. {
  64191. return $this->valid() && $this->current() instanceof \PHPUnit\Framework\TestSuite;
  64192. }
  64193. }
  64194. <?php
  64195. declare (strict_types=1);
  64196. /*
  64197. * This file is part of PHPUnit.
  64198. *
  64199. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64200. *
  64201. * For the full copyright and license information, please view the LICENSE
  64202. * file that was distributed with this source code.
  64203. */
  64204. namespace PHPUnit\Logging;
  64205. use const FILE_APPEND;
  64206. use const LOCK_EX;
  64207. use const PHP_EOL;
  64208. use const PHP_OS_FAMILY;
  64209. use function file_put_contents;
  64210. use function implode;
  64211. use function preg_split;
  64212. use function str_repeat;
  64213. use function strlen;
  64214. use PHPUnit\Event\Event;
  64215. use PHPUnit\Event\Tracer\Tracer;
  64216. /**
  64217. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64218. *
  64219. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64220. */
  64221. final class EventLogger implements Tracer
  64222. {
  64223. private readonly string $path;
  64224. private readonly bool $includeTelemetryInfo;
  64225. public function __construct(string $path, bool $includeTelemetryInfo)
  64226. {
  64227. $this->path = $path;
  64228. $this->includeTelemetryInfo = $includeTelemetryInfo;
  64229. }
  64230. public function trace(Event $event): void
  64231. {
  64232. $telemetryInfo = $this->telemetryInfo($event);
  64233. $indentation = PHP_EOL . str_repeat(' ', strlen($telemetryInfo));
  64234. $lines = preg_split('/\r\n|\r|\n/', $event->asString());
  64235. $flags = FILE_APPEND;
  64236. if (!(PHP_OS_FAMILY === 'Windows' || PHP_OS_FAMILY === 'Darwin') || $this->path !== 'php://stdout') {
  64237. $flags |= LOCK_EX;
  64238. }
  64239. file_put_contents($this->path, $telemetryInfo . implode($indentation, $lines) . PHP_EOL, $flags);
  64240. }
  64241. private function telemetryInfo(Event $event): string
  64242. {
  64243. if (!$this->includeTelemetryInfo) {
  64244. return '';
  64245. }
  64246. return $event->telemetryInfo()->asString() . ' ';
  64247. }
  64248. }
  64249. <?php
  64250. declare (strict_types=1);
  64251. /*
  64252. * This file is part of PHPUnit.
  64253. *
  64254. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64255. *
  64256. * For the full copyright and license information, please view the LICENSE
  64257. * file that was distributed with this source code.
  64258. */
  64259. namespace PHPUnit\Logging\JUnit;
  64260. use const PHP_EOL;
  64261. use function assert;
  64262. use function basename;
  64263. use function is_int;
  64264. use function sprintf;
  64265. use function str_replace;
  64266. use function trim;
  64267. use DOMDocument;
  64268. use DOMElement;
  64269. use PHPUnit\Event\Code\Test;
  64270. use PHPUnit\Event\Code\TestMethod;
  64271. use PHPUnit\Event\EventFacadeIsSealedException;
  64272. use PHPUnit\Event\Facade;
  64273. use PHPUnit\Event\InvalidArgumentException;
  64274. use PHPUnit\Event\Telemetry\HRTime;
  64275. use PHPUnit\Event\Telemetry\Info;
  64276. use PHPUnit\Event\Test\Errored;
  64277. use PHPUnit\Event\Test\Failed;
  64278. use PHPUnit\Event\Test\Finished;
  64279. use PHPUnit\Event\Test\MarkedIncomplete;
  64280. use PHPUnit\Event\Test\PreparationStarted;
  64281. use PHPUnit\Event\Test\Prepared;
  64282. use PHPUnit\Event\Test\Skipped;
  64283. use PHPUnit\Event\TestSuite\Started;
  64284. use PHPUnit\Event\UnknownSubscriberTypeException;
  64285. use PHPUnit\TextUI\Output\Printer;
  64286. use PHPUnit\Util\Xml;
  64287. /**
  64288. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64289. *
  64290. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64291. */
  64292. final class JunitXmlLogger
  64293. {
  64294. private readonly Printer $printer;
  64295. private DOMDocument $document;
  64296. private DOMElement $root;
  64297. /**
  64298. * @var DOMElement[]
  64299. */
  64300. private array $testSuites = [];
  64301. /**
  64302. * @psalm-var array<int,int>
  64303. */
  64304. private array $testSuiteTests = [0];
  64305. /**
  64306. * @psalm-var array<int,int>
  64307. */
  64308. private array $testSuiteAssertions = [0];
  64309. /**
  64310. * @psalm-var array<int,int>
  64311. */
  64312. private array $testSuiteErrors = [0];
  64313. /**
  64314. * @psalm-var array<int,int>
  64315. */
  64316. private array $testSuiteFailures = [0];
  64317. /**
  64318. * @psalm-var array<int,int>
  64319. */
  64320. private array $testSuiteSkipped = [0];
  64321. /**
  64322. * @psalm-var array<int,int>
  64323. */
  64324. private array $testSuiteTimes = [0];
  64325. private int $testSuiteLevel = 0;
  64326. private ?DOMElement $currentTestCase = null;
  64327. private ?HRTime $time = null;
  64328. private bool $prepared = \false;
  64329. private bool $preparationFailed = \false;
  64330. /**
  64331. * @throws EventFacadeIsSealedException
  64332. * @throws UnknownSubscriberTypeException
  64333. */
  64334. public function __construct(Printer $printer, Facade $facade)
  64335. {
  64336. $this->printer = $printer;
  64337. $this->registerSubscribers($facade);
  64338. $this->createDocument();
  64339. }
  64340. public function flush(): void
  64341. {
  64342. $this->printer->print($this->document->saveXML());
  64343. $this->printer->flush();
  64344. }
  64345. public function testSuiteStarted(Started $event): void
  64346. {
  64347. $testSuite = $this->document->createElement('testsuite');
  64348. $testSuite->setAttribute('name', $event->testSuite()->name());
  64349. if ($event->testSuite()->isForTestClass()) {
  64350. $testSuite->setAttribute('file', $event->testSuite()->file());
  64351. }
  64352. if ($this->testSuiteLevel > 0) {
  64353. $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
  64354. } else {
  64355. $this->root->appendChild($testSuite);
  64356. }
  64357. $this->testSuiteLevel++;
  64358. $this->testSuites[$this->testSuiteLevel] = $testSuite;
  64359. $this->testSuiteTests[$this->testSuiteLevel] = 0;
  64360. $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
  64361. $this->testSuiteErrors[$this->testSuiteLevel] = 0;
  64362. $this->testSuiteFailures[$this->testSuiteLevel] = 0;
  64363. $this->testSuiteSkipped[$this->testSuiteLevel] = 0;
  64364. $this->testSuiteTimes[$this->testSuiteLevel] = 0;
  64365. }
  64366. public function testSuiteFinished(): void
  64367. {
  64368. $this->testSuites[$this->testSuiteLevel]->setAttribute('tests', (string) $this->testSuiteTests[$this->testSuiteLevel]);
  64369. $this->testSuites[$this->testSuiteLevel]->setAttribute('assertions', (string) $this->testSuiteAssertions[$this->testSuiteLevel]);
  64370. $this->testSuites[$this->testSuiteLevel]->setAttribute('errors', (string) $this->testSuiteErrors[$this->testSuiteLevel]);
  64371. $this->testSuites[$this->testSuiteLevel]->setAttribute('failures', (string) $this->testSuiteFailures[$this->testSuiteLevel]);
  64372. $this->testSuites[$this->testSuiteLevel]->setAttribute('skipped', (string) $this->testSuiteSkipped[$this->testSuiteLevel]);
  64373. $this->testSuites[$this->testSuiteLevel]->setAttribute('time', sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]));
  64374. if ($this->testSuiteLevel > 1) {
  64375. $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
  64376. $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
  64377. $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
  64378. $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
  64379. $this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel];
  64380. $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
  64381. }
  64382. $this->testSuiteLevel--;
  64383. }
  64384. /**
  64385. * @throws InvalidArgumentException
  64386. */
  64387. public function testPreparationStarted(PreparationStarted $event): void
  64388. {
  64389. $this->createTestCase($event);
  64390. }
  64391. /**
  64392. * @throws InvalidArgumentException
  64393. */
  64394. public function testPreparationFailed(): void
  64395. {
  64396. $this->preparationFailed = \true;
  64397. }
  64398. /**
  64399. * @throws InvalidArgumentException
  64400. */
  64401. public function testPrepared(): void
  64402. {
  64403. $this->prepared = \true;
  64404. }
  64405. /**
  64406. * @throws InvalidArgumentException
  64407. */
  64408. public function testFinished(Finished $event): void
  64409. {
  64410. if (!$this->prepared || $this->preparationFailed) {
  64411. return;
  64412. }
  64413. $this->handleFinish($event->telemetryInfo(), $event->numberOfAssertionsPerformed());
  64414. }
  64415. /**
  64416. * @throws InvalidArgumentException
  64417. */
  64418. public function testMarkedIncomplete(MarkedIncomplete $event): void
  64419. {
  64420. $this->handleIncompleteOrSkipped($event);
  64421. }
  64422. /**
  64423. * @throws InvalidArgumentException
  64424. */
  64425. public function testSkipped(Skipped $event): void
  64426. {
  64427. $this->handleIncompleteOrSkipped($event);
  64428. }
  64429. /**
  64430. * @throws InvalidArgumentException
  64431. */
  64432. public function testErrored(Errored $event): void
  64433. {
  64434. $this->handleFault($event, 'error');
  64435. $this->testSuiteErrors[$this->testSuiteLevel]++;
  64436. }
  64437. /**
  64438. * @throws InvalidArgumentException
  64439. */
  64440. public function testFailed(Failed $event): void
  64441. {
  64442. $this->handleFault($event, 'failure');
  64443. $this->testSuiteFailures[$this->testSuiteLevel]++;
  64444. }
  64445. /**
  64446. * @throws InvalidArgumentException
  64447. */
  64448. private function handleFinish(Info $telemetryInfo, int $numberOfAssertionsPerformed): void
  64449. {
  64450. assert($this->currentTestCase !== null);
  64451. assert($this->time !== null);
  64452. $time = $telemetryInfo->time()->duration($this->time)->asFloat();
  64453. $this->testSuiteAssertions[$this->testSuiteLevel] += $numberOfAssertionsPerformed;
  64454. $this->currentTestCase->setAttribute('assertions', (string) $numberOfAssertionsPerformed);
  64455. $this->currentTestCase->setAttribute('time', sprintf('%F', $time));
  64456. $this->testSuites[$this->testSuiteLevel]->appendChild($this->currentTestCase);
  64457. $this->testSuiteTests[$this->testSuiteLevel]++;
  64458. $this->testSuiteTimes[$this->testSuiteLevel] += $time;
  64459. $this->currentTestCase = null;
  64460. $this->time = null;
  64461. $this->prepared = \false;
  64462. }
  64463. /**
  64464. * @throws EventFacadeIsSealedException
  64465. * @throws UnknownSubscriberTypeException
  64466. */
  64467. private function registerSubscribers(Facade $facade): void
  64468. {
  64469. $facade->registerSubscribers(new \PHPUnit\Logging\JUnit\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\JUnit\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparationStartedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparationFailedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparedSubscriber($this), new \PHPUnit\Logging\JUnit\TestFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestErroredSubscriber($this), new \PHPUnit\Logging\JUnit\TestFailedSubscriber($this), new \PHPUnit\Logging\JUnit\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\JUnit\TestSkippedSubscriber($this), new \PHPUnit\Logging\JUnit\TestRunnerExecutionFinishedSubscriber($this));
  64470. }
  64471. private function createDocument(): void
  64472. {
  64473. $this->document = new DOMDocument('1.0', 'UTF-8');
  64474. $this->document->formatOutput = \true;
  64475. $this->root = $this->document->createElement('testsuites');
  64476. $this->document->appendChild($this->root);
  64477. }
  64478. /**
  64479. * @throws InvalidArgumentException
  64480. */
  64481. private function handleFault(Errored|Failed $event, string $type): void
  64482. {
  64483. if (!$this->prepared) {
  64484. $this->createTestCase($event);
  64485. }
  64486. assert($this->currentTestCase !== null);
  64487. $buffer = $this->testAsString($event->test());
  64488. $throwable = $event->throwable();
  64489. $buffer .= trim($throwable->description() . PHP_EOL . $throwable->stackTrace());
  64490. $fault = $this->document->createElement($type, Xml::prepareString($buffer));
  64491. $fault->setAttribute('type', $throwable->className());
  64492. $this->currentTestCase->appendChild($fault);
  64493. if (!$this->prepared) {
  64494. $this->handleFinish($event->telemetryInfo(), 0);
  64495. }
  64496. }
  64497. /**
  64498. * @throws InvalidArgumentException
  64499. */
  64500. private function handleIncompleteOrSkipped(MarkedIncomplete|Skipped $event): void
  64501. {
  64502. if (!$this->prepared) {
  64503. $this->createTestCase($event);
  64504. }
  64505. assert($this->currentTestCase !== null);
  64506. $skipped = $this->document->createElement('skipped');
  64507. $this->currentTestCase->appendChild($skipped);
  64508. $this->testSuiteSkipped[$this->testSuiteLevel]++;
  64509. if (!$this->prepared) {
  64510. $this->handleFinish($event->telemetryInfo(), 0);
  64511. }
  64512. }
  64513. /**
  64514. * @throws InvalidArgumentException
  64515. */
  64516. private function testAsString(Test $test): string
  64517. {
  64518. if ($test->isPhpt()) {
  64519. return basename($test->file());
  64520. }
  64521. assert($test instanceof TestMethod);
  64522. return sprintf('%s::%s%s', $test->className(), $this->name($test), PHP_EOL);
  64523. }
  64524. /**
  64525. * @throws InvalidArgumentException
  64526. */
  64527. private function name(Test $test): string
  64528. {
  64529. if ($test->isPhpt()) {
  64530. return basename($test->file());
  64531. }
  64532. assert($test instanceof TestMethod);
  64533. if (!$test->testData()->hasDataFromDataProvider()) {
  64534. return $test->methodName();
  64535. }
  64536. $dataSetName = $test->testData()->dataFromDataProvider()->dataSetName();
  64537. if (is_int($dataSetName)) {
  64538. return sprintf('%s with data set #%d', $test->methodName(), $dataSetName);
  64539. }
  64540. return sprintf('%s with data set "%s"', $test->methodName(), $dataSetName);
  64541. }
  64542. /**
  64543. * @throws InvalidArgumentException
  64544. *
  64545. * @psalm-assert !null $this->currentTestCase
  64546. */
  64547. private function createTestCase(Errored|Failed|MarkedIncomplete|PreparationStarted|Prepared|Skipped $event): void
  64548. {
  64549. $testCase = $this->document->createElement('testcase');
  64550. $test = $event->test();
  64551. $testCase->setAttribute('name', $this->name($test));
  64552. $testCase->setAttribute('file', $test->file());
  64553. if ($test->isTestMethod()) {
  64554. assert($test instanceof TestMethod);
  64555. $testCase->setAttribute('line', (string) $test->line());
  64556. $testCase->setAttribute('class', $test->className());
  64557. $testCase->setAttribute('classname', str_replace('\\', '.', $test->className()));
  64558. }
  64559. $this->currentTestCase = $testCase;
  64560. $this->time = $event->telemetryInfo()->time();
  64561. }
  64562. }
  64563. <?php
  64564. declare (strict_types=1);
  64565. /*
  64566. * This file is part of PHPUnit.
  64567. *
  64568. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64569. *
  64570. * For the full copyright and license information, please view the LICENSE
  64571. * file that was distributed with this source code.
  64572. */
  64573. namespace PHPUnit\Logging\JUnit;
  64574. /**
  64575. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64576. *
  64577. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64578. */
  64579. abstract class Subscriber
  64580. {
  64581. private readonly \PHPUnit\Logging\JUnit\JunitXmlLogger $logger;
  64582. public function __construct(\PHPUnit\Logging\JUnit\JunitXmlLogger $logger)
  64583. {
  64584. $this->logger = $logger;
  64585. }
  64586. protected function logger(): \PHPUnit\Logging\JUnit\JunitXmlLogger
  64587. {
  64588. return $this->logger;
  64589. }
  64590. }
  64591. <?php
  64592. declare (strict_types=1);
  64593. /*
  64594. * This file is part of PHPUnit.
  64595. *
  64596. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64597. *
  64598. * For the full copyright and license information, please view the LICENSE
  64599. * file that was distributed with this source code.
  64600. */
  64601. namespace PHPUnit\Logging\JUnit;
  64602. use PHPUnit\Event\InvalidArgumentException;
  64603. use PHPUnit\Event\Test\Errored;
  64604. use PHPUnit\Event\Test\ErroredSubscriber;
  64605. /**
  64606. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64607. *
  64608. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64609. */
  64610. final class TestErroredSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements ErroredSubscriber
  64611. {
  64612. /**
  64613. * @throws InvalidArgumentException
  64614. */
  64615. public function notify(Errored $event): void
  64616. {
  64617. $this->logger()->testErrored($event);
  64618. }
  64619. }
  64620. <?php
  64621. declare (strict_types=1);
  64622. /*
  64623. * This file is part of PHPUnit.
  64624. *
  64625. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64626. *
  64627. * For the full copyright and license information, please view the LICENSE
  64628. * file that was distributed with this source code.
  64629. */
  64630. namespace PHPUnit\Logging\JUnit;
  64631. use PHPUnit\Event\InvalidArgumentException;
  64632. use PHPUnit\Event\Test\Failed;
  64633. use PHPUnit\Event\Test\FailedSubscriber;
  64634. /**
  64635. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64636. *
  64637. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64638. */
  64639. final class TestFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FailedSubscriber
  64640. {
  64641. /**
  64642. * @throws InvalidArgumentException
  64643. */
  64644. public function notify(Failed $event): void
  64645. {
  64646. $this->logger()->testFailed($event);
  64647. }
  64648. }
  64649. <?php
  64650. declare (strict_types=1);
  64651. /*
  64652. * This file is part of PHPUnit.
  64653. *
  64654. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64655. *
  64656. * For the full copyright and license information, please view the LICENSE
  64657. * file that was distributed with this source code.
  64658. */
  64659. namespace PHPUnit\Logging\JUnit;
  64660. use PHPUnit\Event\InvalidArgumentException;
  64661. use PHPUnit\Event\Test\Finished;
  64662. use PHPUnit\Event\Test\FinishedSubscriber;
  64663. /**
  64664. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64665. *
  64666. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64667. */
  64668. final class TestFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FinishedSubscriber
  64669. {
  64670. /**
  64671. * @throws InvalidArgumentException
  64672. */
  64673. public function notify(Finished $event): void
  64674. {
  64675. $this->logger()->testFinished($event);
  64676. }
  64677. }
  64678. <?php
  64679. declare (strict_types=1);
  64680. /*
  64681. * This file is part of PHPUnit.
  64682. *
  64683. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64684. *
  64685. * For the full copyright and license information, please view the LICENSE
  64686. * file that was distributed with this source code.
  64687. */
  64688. namespace PHPUnit\Logging\JUnit;
  64689. use PHPUnit\Event\InvalidArgumentException;
  64690. use PHPUnit\Event\Test\MarkedIncomplete;
  64691. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  64692. /**
  64693. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64694. *
  64695. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64696. */
  64697. final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements MarkedIncompleteSubscriber
  64698. {
  64699. /**
  64700. * @throws InvalidArgumentException
  64701. */
  64702. public function notify(MarkedIncomplete $event): void
  64703. {
  64704. $this->logger()->testMarkedIncomplete($event);
  64705. }
  64706. }
  64707. <?php
  64708. declare (strict_types=1);
  64709. /*
  64710. * This file is part of PHPUnit.
  64711. *
  64712. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64713. *
  64714. * For the full copyright and license information, please view the LICENSE
  64715. * file that was distributed with this source code.
  64716. */
  64717. namespace PHPUnit\Logging\JUnit;
  64718. use PHPUnit\Event\InvalidArgumentException;
  64719. use PHPUnit\Event\Test\PreparationFailed;
  64720. use PHPUnit\Event\Test\PreparationFailedSubscriber;
  64721. /**
  64722. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64723. *
  64724. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64725. */
  64726. final class TestPreparationFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationFailedSubscriber
  64727. {
  64728. /**
  64729. * @throws InvalidArgumentException
  64730. */
  64731. public function notify(PreparationFailed $event): void
  64732. {
  64733. $this->logger()->testPreparationFailed();
  64734. }
  64735. }
  64736. <?php
  64737. declare (strict_types=1);
  64738. /*
  64739. * This file is part of PHPUnit.
  64740. *
  64741. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64742. *
  64743. * For the full copyright and license information, please view the LICENSE
  64744. * file that was distributed with this source code.
  64745. */
  64746. namespace PHPUnit\Logging\JUnit;
  64747. use PHPUnit\Event\InvalidArgumentException;
  64748. use PHPUnit\Event\Test\PreparationStarted;
  64749. use PHPUnit\Event\Test\PreparationStartedSubscriber;
  64750. /**
  64751. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64752. *
  64753. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64754. */
  64755. final class TestPreparationStartedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationStartedSubscriber
  64756. {
  64757. /**
  64758. * @throws InvalidArgumentException
  64759. */
  64760. public function notify(PreparationStarted $event): void
  64761. {
  64762. $this->logger()->testPreparationStarted($event);
  64763. }
  64764. }
  64765. <?php
  64766. declare (strict_types=1);
  64767. /*
  64768. * This file is part of PHPUnit.
  64769. *
  64770. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64771. *
  64772. * For the full copyright and license information, please view the LICENSE
  64773. * file that was distributed with this source code.
  64774. */
  64775. namespace PHPUnit\Logging\JUnit;
  64776. use PHPUnit\Event\InvalidArgumentException;
  64777. use PHPUnit\Event\Test\Prepared;
  64778. use PHPUnit\Event\Test\PreparedSubscriber;
  64779. /**
  64780. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64781. *
  64782. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64783. */
  64784. final class TestPreparedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparedSubscriber
  64785. {
  64786. /**
  64787. * @throws InvalidArgumentException
  64788. */
  64789. public function notify(Prepared $event): void
  64790. {
  64791. $this->logger()->testPrepared();
  64792. }
  64793. }
  64794. <?php
  64795. declare (strict_types=1);
  64796. /*
  64797. * This file is part of PHPUnit.
  64798. *
  64799. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64800. *
  64801. * For the full copyright and license information, please view the LICENSE
  64802. * file that was distributed with this source code.
  64803. */
  64804. namespace PHPUnit\Logging\JUnit;
  64805. use PHPUnit\Event\TestRunner\ExecutionFinished;
  64806. use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber;
  64807. /**
  64808. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64809. *
  64810. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64811. */
  64812. final class TestRunnerExecutionFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements ExecutionFinishedSubscriber
  64813. {
  64814. public function notify(ExecutionFinished $event): void
  64815. {
  64816. $this->logger()->flush();
  64817. }
  64818. }
  64819. <?php
  64820. declare (strict_types=1);
  64821. /*
  64822. * This file is part of PHPUnit.
  64823. *
  64824. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64825. *
  64826. * For the full copyright and license information, please view the LICENSE
  64827. * file that was distributed with this source code.
  64828. */
  64829. namespace PHPUnit\Logging\JUnit;
  64830. use PHPUnit\Event\InvalidArgumentException;
  64831. use PHPUnit\Event\Test\Skipped;
  64832. use PHPUnit\Event\Test\SkippedSubscriber;
  64833. /**
  64834. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64835. *
  64836. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64837. */
  64838. final class TestSkippedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements SkippedSubscriber
  64839. {
  64840. /**
  64841. * @throws InvalidArgumentException
  64842. */
  64843. public function notify(Skipped $event): void
  64844. {
  64845. $this->logger()->testSkipped($event);
  64846. }
  64847. }
  64848. <?php
  64849. declare (strict_types=1);
  64850. /*
  64851. * This file is part of PHPUnit.
  64852. *
  64853. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64854. *
  64855. * For the full copyright and license information, please view the LICENSE
  64856. * file that was distributed with this source code.
  64857. */
  64858. namespace PHPUnit\Logging\JUnit;
  64859. use PHPUnit\Event\TestSuite\Finished;
  64860. use PHPUnit\Event\TestSuite\FinishedSubscriber;
  64861. /**
  64862. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64863. *
  64864. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64865. */
  64866. final class TestSuiteFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FinishedSubscriber
  64867. {
  64868. public function notify(Finished $event): void
  64869. {
  64870. $this->logger()->testSuiteFinished();
  64871. }
  64872. }
  64873. <?php
  64874. declare (strict_types=1);
  64875. /*
  64876. * This file is part of PHPUnit.
  64877. *
  64878. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64879. *
  64880. * For the full copyright and license information, please view the LICENSE
  64881. * file that was distributed with this source code.
  64882. */
  64883. namespace PHPUnit\Logging\JUnit;
  64884. use PHPUnit\Event\TestSuite\Started;
  64885. use PHPUnit\Event\TestSuite\StartedSubscriber;
  64886. /**
  64887. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64888. *
  64889. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64890. */
  64891. final class TestSuiteStartedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements StartedSubscriber
  64892. {
  64893. public function notify(Started $event): void
  64894. {
  64895. $this->logger()->testSuiteStarted($event);
  64896. }
  64897. }
  64898. <?php
  64899. declare (strict_types=1);
  64900. /*
  64901. * This file is part of PHPUnit.
  64902. *
  64903. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64904. *
  64905. * For the full copyright and license information, please view the LICENSE
  64906. * file that was distributed with this source code.
  64907. */
  64908. namespace PHPUnit\Logging\TeamCity;
  64909. /**
  64910. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64911. *
  64912. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64913. */
  64914. abstract class Subscriber
  64915. {
  64916. private readonly \PHPUnit\Logging\TeamCity\TeamCityLogger $logger;
  64917. public function __construct(\PHPUnit\Logging\TeamCity\TeamCityLogger $logger)
  64918. {
  64919. $this->logger = $logger;
  64920. }
  64921. protected function logger(): \PHPUnit\Logging\TeamCity\TeamCityLogger
  64922. {
  64923. return $this->logger;
  64924. }
  64925. }
  64926. <?php
  64927. declare (strict_types=1);
  64928. /*
  64929. * This file is part of PHPUnit.
  64930. *
  64931. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64932. *
  64933. * For the full copyright and license information, please view the LICENSE
  64934. * file that was distributed with this source code.
  64935. */
  64936. namespace PHPUnit\Logging\TeamCity;
  64937. use PHPUnit\Event\InvalidArgumentException;
  64938. use PHPUnit\Event\Test\ConsideredRisky;
  64939. use PHPUnit\Event\Test\ConsideredRiskySubscriber;
  64940. /**
  64941. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64942. *
  64943. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64944. */
  64945. final class TestConsideredRiskySubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ConsideredRiskySubscriber
  64946. {
  64947. /**
  64948. * @throws InvalidArgumentException
  64949. */
  64950. public function notify(ConsideredRisky $event): void
  64951. {
  64952. $this->logger()->testConsideredRisky($event);
  64953. }
  64954. }
  64955. <?php
  64956. declare (strict_types=1);
  64957. /*
  64958. * This file is part of PHPUnit.
  64959. *
  64960. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64961. *
  64962. * For the full copyright and license information, please view the LICENSE
  64963. * file that was distributed with this source code.
  64964. */
  64965. namespace PHPUnit\Logging\TeamCity;
  64966. use PHPUnit\Event\InvalidArgumentException;
  64967. use PHPUnit\Event\Test\Errored;
  64968. use PHPUnit\Event\Test\ErroredSubscriber;
  64969. /**
  64970. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  64971. *
  64972. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  64973. */
  64974. final class TestErroredSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ErroredSubscriber
  64975. {
  64976. /**
  64977. * @throws InvalidArgumentException
  64978. */
  64979. public function notify(Errored $event): void
  64980. {
  64981. $this->logger()->testErrored($event);
  64982. }
  64983. }
  64984. <?php
  64985. declare (strict_types=1);
  64986. /*
  64987. * This file is part of PHPUnit.
  64988. *
  64989. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64990. *
  64991. * For the full copyright and license information, please view the LICENSE
  64992. * file that was distributed with this source code.
  64993. */
  64994. namespace PHPUnit\Logging\TeamCity;
  64995. use PHPUnit\Event\InvalidArgumentException;
  64996. use PHPUnit\Event\Test\Failed;
  64997. use PHPUnit\Event\Test\FailedSubscriber;
  64998. /**
  64999. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65000. *
  65001. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65002. */
  65003. final class TestFailedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FailedSubscriber
  65004. {
  65005. /**
  65006. * @throws InvalidArgumentException
  65007. */
  65008. public function notify(Failed $event): void
  65009. {
  65010. $this->logger()->testFailed($event);
  65011. }
  65012. }
  65013. <?php
  65014. declare (strict_types=1);
  65015. /*
  65016. * This file is part of PHPUnit.
  65017. *
  65018. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65019. *
  65020. * For the full copyright and license information, please view the LICENSE
  65021. * file that was distributed with this source code.
  65022. */
  65023. namespace PHPUnit\Logging\TeamCity;
  65024. use PHPUnit\Event\InvalidArgumentException;
  65025. use PHPUnit\Event\Test\Finished;
  65026. use PHPUnit\Event\Test\FinishedSubscriber;
  65027. /**
  65028. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65029. *
  65030. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65031. */
  65032. final class TestFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FinishedSubscriber
  65033. {
  65034. /**
  65035. * @throws InvalidArgumentException
  65036. */
  65037. public function notify(Finished $event): void
  65038. {
  65039. $this->logger()->testFinished($event);
  65040. }
  65041. }
  65042. <?php
  65043. declare (strict_types=1);
  65044. /*
  65045. * This file is part of PHPUnit.
  65046. *
  65047. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65048. *
  65049. * For the full copyright and license information, please view the LICENSE
  65050. * file that was distributed with this source code.
  65051. */
  65052. namespace PHPUnit\Logging\TeamCity;
  65053. use PHPUnit\Event\InvalidArgumentException;
  65054. use PHPUnit\Event\Test\MarkedIncomplete;
  65055. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  65056. /**
  65057. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65058. *
  65059. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65060. */
  65061. final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements MarkedIncompleteSubscriber
  65062. {
  65063. /**
  65064. * @throws InvalidArgumentException
  65065. */
  65066. public function notify(MarkedIncomplete $event): void
  65067. {
  65068. $this->logger()->testMarkedIncomplete($event);
  65069. }
  65070. }
  65071. <?php
  65072. declare (strict_types=1);
  65073. /*
  65074. * This file is part of PHPUnit.
  65075. *
  65076. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65077. *
  65078. * For the full copyright and license information, please view the LICENSE
  65079. * file that was distributed with this source code.
  65080. */
  65081. namespace PHPUnit\Logging\TeamCity;
  65082. use PHPUnit\Event\Test\Prepared;
  65083. use PHPUnit\Event\Test\PreparedSubscriber;
  65084. /**
  65085. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65086. *
  65087. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65088. */
  65089. final class TestPreparedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements PreparedSubscriber
  65090. {
  65091. public function notify(Prepared $event): void
  65092. {
  65093. $this->logger()->testPrepared($event);
  65094. }
  65095. }
  65096. <?php
  65097. declare (strict_types=1);
  65098. /*
  65099. * This file is part of PHPUnit.
  65100. *
  65101. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65102. *
  65103. * For the full copyright and license information, please view the LICENSE
  65104. * file that was distributed with this source code.
  65105. */
  65106. namespace PHPUnit\Logging\TeamCity;
  65107. use PHPUnit\Event\TestRunner\ExecutionFinished;
  65108. use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber;
  65109. /**
  65110. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65111. *
  65112. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65113. */
  65114. final class TestRunnerExecutionFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ExecutionFinishedSubscriber
  65115. {
  65116. public function notify(ExecutionFinished $event): void
  65117. {
  65118. $this->logger()->flush();
  65119. }
  65120. }
  65121. <?php
  65122. declare (strict_types=1);
  65123. /*
  65124. * This file is part of PHPUnit.
  65125. *
  65126. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65127. *
  65128. * For the full copyright and license information, please view the LICENSE
  65129. * file that was distributed with this source code.
  65130. */
  65131. namespace PHPUnit\Logging\TeamCity;
  65132. use PHPUnit\Event\InvalidArgumentException;
  65133. use PHPUnit\Event\Test\Skipped;
  65134. use PHPUnit\Event\Test\SkippedSubscriber;
  65135. /**
  65136. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65137. *
  65138. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65139. */
  65140. final class TestSkippedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements SkippedSubscriber
  65141. {
  65142. /**
  65143. * @throws InvalidArgumentException
  65144. */
  65145. public function notify(Skipped $event): void
  65146. {
  65147. $this->logger()->testSkipped($event);
  65148. }
  65149. }
  65150. <?php
  65151. declare (strict_types=1);
  65152. /*
  65153. * This file is part of PHPUnit.
  65154. *
  65155. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65156. *
  65157. * For the full copyright and license information, please view the LICENSE
  65158. * file that was distributed with this source code.
  65159. */
  65160. namespace PHPUnit\Logging\TeamCity;
  65161. use PHPUnit\Event\InvalidArgumentException;
  65162. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  65163. use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
  65164. /**
  65165. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65166. *
  65167. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65168. */
  65169. final class TestSuiteBeforeFirstTestMethodErroredSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements BeforeFirstTestMethodErroredSubscriber
  65170. {
  65171. /**
  65172. * @throws InvalidArgumentException
  65173. */
  65174. public function notify(BeforeFirstTestMethodErrored $event): void
  65175. {
  65176. $this->logger()->beforeFirstTestMethodErrored($event);
  65177. }
  65178. }
  65179. <?php
  65180. declare (strict_types=1);
  65181. /*
  65182. * This file is part of PHPUnit.
  65183. *
  65184. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65185. *
  65186. * For the full copyright and license information, please view the LICENSE
  65187. * file that was distributed with this source code.
  65188. */
  65189. namespace PHPUnit\Logging\TeamCity;
  65190. use PHPUnit\Event\TestSuite\Finished;
  65191. use PHPUnit\Event\TestSuite\FinishedSubscriber;
  65192. /**
  65193. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65194. *
  65195. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65196. */
  65197. final class TestSuiteFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FinishedSubscriber
  65198. {
  65199. public function notify(Finished $event): void
  65200. {
  65201. $this->logger()->testSuiteFinished($event);
  65202. }
  65203. }
  65204. <?php
  65205. declare (strict_types=1);
  65206. /*
  65207. * This file is part of PHPUnit.
  65208. *
  65209. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65210. *
  65211. * For the full copyright and license information, please view the LICENSE
  65212. * file that was distributed with this source code.
  65213. */
  65214. namespace PHPUnit\Logging\TeamCity;
  65215. use PHPUnit\Event\InvalidArgumentException;
  65216. use PHPUnit\Event\TestSuite\Skipped;
  65217. use PHPUnit\Event\TestSuite\SkippedSubscriber;
  65218. /**
  65219. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65220. *
  65221. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65222. */
  65223. final class TestSuiteSkippedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements SkippedSubscriber
  65224. {
  65225. /**
  65226. * @throws InvalidArgumentException
  65227. */
  65228. public function notify(Skipped $event): void
  65229. {
  65230. $this->logger()->testSuiteSkipped($event);
  65231. }
  65232. }
  65233. <?php
  65234. declare (strict_types=1);
  65235. /*
  65236. * This file is part of PHPUnit.
  65237. *
  65238. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65239. *
  65240. * For the full copyright and license information, please view the LICENSE
  65241. * file that was distributed with this source code.
  65242. */
  65243. namespace PHPUnit\Logging\TeamCity;
  65244. use PHPUnit\Event\TestSuite\Started;
  65245. use PHPUnit\Event\TestSuite\StartedSubscriber;
  65246. /**
  65247. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65248. *
  65249. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65250. */
  65251. final class TestSuiteStartedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements StartedSubscriber
  65252. {
  65253. public function notify(Started $event): void
  65254. {
  65255. $this->logger()->testSuiteStarted($event);
  65256. }
  65257. }
  65258. <?php
  65259. declare (strict_types=1);
  65260. /*
  65261. * This file is part of PHPUnit.
  65262. *
  65263. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65264. *
  65265. * For the full copyright and license information, please view the LICENSE
  65266. * file that was distributed with this source code.
  65267. */
  65268. namespace PHPUnit\Logging\TeamCity;
  65269. use function assert;
  65270. use function getmypid;
  65271. use function ini_get;
  65272. use function is_a;
  65273. use function round;
  65274. use function sprintf;
  65275. use function str_replace;
  65276. use function stripos;
  65277. use PHPUnit\Event\Code\TestMethod;
  65278. use PHPUnit\Event\Code\Throwable;
  65279. use PHPUnit\Event\Event;
  65280. use PHPUnit\Event\EventFacadeIsSealedException;
  65281. use PHPUnit\Event\Facade;
  65282. use PHPUnit\Event\InvalidArgumentException;
  65283. use PHPUnit\Event\Telemetry\HRTime;
  65284. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  65285. use PHPUnit\Event\Test\ConsideredRisky;
  65286. use PHPUnit\Event\Test\Errored;
  65287. use PHPUnit\Event\Test\Failed;
  65288. use PHPUnit\Event\Test\Finished;
  65289. use PHPUnit\Event\Test\MarkedIncomplete;
  65290. use PHPUnit\Event\Test\Prepared;
  65291. use PHPUnit\Event\Test\Skipped;
  65292. use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
  65293. use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
  65294. use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
  65295. use PHPUnit\Event\TestSuite\TestSuiteForTestClass;
  65296. use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
  65297. use PHPUnit\Event\UnknownSubscriberTypeException;
  65298. use PHPUnit\Framework\Exception as FrameworkException;
  65299. use PHPUnit\TextUI\Output\Printer;
  65300. /**
  65301. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65302. *
  65303. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65304. */
  65305. final class TeamCityLogger
  65306. {
  65307. private readonly Printer $printer;
  65308. private bool $isSummaryTestCountPrinted = \false;
  65309. private ?HRTime $time = null;
  65310. private ?int $flowId;
  65311. /**
  65312. * @throws EventFacadeIsSealedException
  65313. * @throws UnknownSubscriberTypeException
  65314. */
  65315. public function __construct(Printer $printer, Facade $facade)
  65316. {
  65317. $this->printer = $printer;
  65318. $this->registerSubscribers($facade);
  65319. $this->setFlowId();
  65320. }
  65321. public function testSuiteStarted(TestSuiteStarted $event): void
  65322. {
  65323. $testSuite = $event->testSuite();
  65324. if (!$this->isSummaryTestCountPrinted) {
  65325. $this->isSummaryTestCountPrinted = \true;
  65326. $this->writeMessage('testCount', ['count' => $testSuite->count()]);
  65327. }
  65328. $parameters = ['name' => $testSuite->name()];
  65329. if ($testSuite->isForTestClass()) {
  65330. assert($testSuite instanceof TestSuiteForTestClass);
  65331. $parameters['locationHint'] = sprintf('php_qn://%s::\%s', $testSuite->file(), $testSuite->name());
  65332. } elseif ($testSuite->isForTestMethodWithDataProvider()) {
  65333. assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
  65334. $parameters['locationHint'] = sprintf('php_qn://%s::\%s', $testSuite->file(), $testSuite->name());
  65335. $parameters['name'] = $testSuite->methodName();
  65336. }
  65337. $this->writeMessage('testSuiteStarted', $parameters);
  65338. }
  65339. public function testSuiteFinished(TestSuiteFinished $event): void
  65340. {
  65341. $testSuite = $event->testSuite();
  65342. $parameters = ['name' => $testSuite->name()];
  65343. if ($testSuite->isForTestMethodWithDataProvider()) {
  65344. assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
  65345. $parameters['name'] = $testSuite->methodName();
  65346. }
  65347. $this->writeMessage('testSuiteFinished', $parameters);
  65348. }
  65349. public function testPrepared(Prepared $event): void
  65350. {
  65351. $test = $event->test();
  65352. $parameters = ['name' => $test->name()];
  65353. if ($test->isTestMethod()) {
  65354. assert($test instanceof TestMethod);
  65355. $parameters['locationHint'] = sprintf('php_qn://%s::\%s::%s', $test->file(), $test->className(), $test->name());
  65356. }
  65357. $this->writeMessage('testStarted', $parameters);
  65358. $this->time = $event->telemetryInfo()->time();
  65359. }
  65360. /**
  65361. * @throws InvalidArgumentException
  65362. */
  65363. public function testMarkedIncomplete(MarkedIncomplete $event): void
  65364. {
  65365. if ($this->time === null) {
  65366. // @codeCoverageIgnoreStart
  65367. $this->time = $event->telemetryInfo()->time();
  65368. // @codeCoverageIgnoreEnd
  65369. }
  65370. $this->writeMessage('testIgnored', ['name' => $event->test()->name(), 'message' => $event->throwable()->message(), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)]);
  65371. }
  65372. /**
  65373. * @throws InvalidArgumentException
  65374. */
  65375. public function testSkipped(Skipped $event): void
  65376. {
  65377. if ($this->time === null) {
  65378. $this->time = $event->telemetryInfo()->time();
  65379. }
  65380. $parameters = ['name' => $event->test()->name(), 'message' => $event->message()];
  65381. $parameters['duration'] = $this->duration($event);
  65382. $this->writeMessage('testIgnored', $parameters);
  65383. }
  65384. /**
  65385. * @throws InvalidArgumentException
  65386. */
  65387. public function testSuiteSkipped(TestSuiteSkipped $event): void
  65388. {
  65389. if ($this->time === null) {
  65390. $this->time = $event->telemetryInfo()->time();
  65391. }
  65392. $parameters = ['name' => $event->testSuite()->name(), 'message' => $event->message()];
  65393. $parameters['duration'] = $this->duration($event);
  65394. $this->writeMessage('testIgnored', $parameters);
  65395. $this->writeMessage('testSuiteFinished', $parameters);
  65396. }
  65397. /**
  65398. * @throws InvalidArgumentException
  65399. */
  65400. public function beforeFirstTestMethodErrored(BeforeFirstTestMethodErrored $event): void
  65401. {
  65402. if ($this->time === null) {
  65403. $this->time = $event->telemetryInfo()->time();
  65404. }
  65405. $parameters = ['name' => $event->testClassName(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)];
  65406. $this->writeMessage('testFailed', $parameters);
  65407. $this->writeMessage('testSuiteFinished', $parameters);
  65408. }
  65409. /**
  65410. * @throws InvalidArgumentException
  65411. */
  65412. public function testErrored(Errored $event): void
  65413. {
  65414. if ($this->time === null) {
  65415. $this->time = $event->telemetryInfo()->time();
  65416. }
  65417. $this->writeMessage('testFailed', ['name' => $event->test()->name(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)]);
  65418. }
  65419. /**
  65420. * @throws InvalidArgumentException
  65421. */
  65422. public function testFailed(Failed $event): void
  65423. {
  65424. if ($this->time === null) {
  65425. // @codeCoverageIgnoreStart
  65426. $this->time = $event->telemetryInfo()->time();
  65427. // @codeCoverageIgnoreEnd
  65428. }
  65429. $parameters = ['name' => $event->test()->name(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)];
  65430. if ($event->hasComparisonFailure()) {
  65431. $parameters['type'] = 'comparisonFailure';
  65432. $parameters['actual'] = $event->comparisonFailure()->actual();
  65433. $parameters['expected'] = $event->comparisonFailure()->expected();
  65434. }
  65435. $this->writeMessage('testFailed', $parameters);
  65436. }
  65437. /**
  65438. * @throws InvalidArgumentException
  65439. */
  65440. public function testConsideredRisky(ConsideredRisky $event): void
  65441. {
  65442. if ($this->time === null) {
  65443. // @codeCoverageIgnoreStart
  65444. $this->time = $event->telemetryInfo()->time();
  65445. // @codeCoverageIgnoreEnd
  65446. }
  65447. $this->writeMessage('testFailed', ['name' => $event->test()->name(), 'message' => $event->message(), 'details' => '', 'duration' => $this->duration($event)]);
  65448. }
  65449. /**
  65450. * @throws InvalidArgumentException
  65451. */
  65452. public function testFinished(Finished $event): void
  65453. {
  65454. $this->writeMessage('testFinished', ['name' => $event->test()->name(), 'duration' => $this->duration($event)]);
  65455. $this->time = null;
  65456. }
  65457. public function flush(): void
  65458. {
  65459. $this->printer->flush();
  65460. }
  65461. /**
  65462. * @throws EventFacadeIsSealedException
  65463. * @throws UnknownSubscriberTypeException
  65464. */
  65465. private function registerSubscribers(Facade $facade): void
  65466. {
  65467. $facade->registerSubscribers(new \PHPUnit\Logging\TeamCity\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestPreparedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestErroredSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFailedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSkippedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteSkippedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TeamCity\TestRunnerExecutionFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteBeforeFirstTestMethodErroredSubscriber($this));
  65468. }
  65469. private function setFlowId(): void
  65470. {
  65471. if (stripos(ini_get('disable_functions'), 'getmypid') === \false) {
  65472. $this->flowId = getmypid();
  65473. }
  65474. }
  65475. private function writeMessage(string $eventName, array $parameters = []): void
  65476. {
  65477. $this->printer->print(sprintf('##teamcity[%s', $eventName));
  65478. if ($this->flowId !== null) {
  65479. $parameters['flowId'] = $this->flowId;
  65480. }
  65481. foreach ($parameters as $key => $value) {
  65482. $this->printer->print(sprintf(" %s='%s'", $key, $this->escape((string) $value)));
  65483. }
  65484. $this->printer->print("]\n");
  65485. }
  65486. /**
  65487. * @throws InvalidArgumentException
  65488. */
  65489. private function duration(Event $event): int
  65490. {
  65491. if ($this->time === null) {
  65492. // @codeCoverageIgnoreStart
  65493. return 0;
  65494. // @codeCoverageIgnoreEnd
  65495. }
  65496. return (int) round($event->telemetryInfo()->time()->duration($this->time)->asFloat() * 1000);
  65497. }
  65498. private function escape(string $string): string
  65499. {
  65500. return str_replace(['|', "'", "\n", "\r", ']', '['], ['||', "|'", '|n', '|r', '|]', '|['], $string);
  65501. }
  65502. private function message(Throwable $throwable): string
  65503. {
  65504. if (is_a($throwable->className(), FrameworkException::class, \true)) {
  65505. return $throwable->message();
  65506. }
  65507. $buffer = $throwable->className();
  65508. if (!empty($throwable->message())) {
  65509. $buffer .= ': ' . $throwable->message();
  65510. }
  65511. return $buffer;
  65512. }
  65513. private function details(Throwable $throwable): string
  65514. {
  65515. $buffer = $throwable->stackTrace();
  65516. while ($throwable->hasPrevious()) {
  65517. $throwable = $throwable->previous();
  65518. $buffer .= sprintf("\nCaused by\n%s\n%s", $throwable->description(), $throwable->stackTrace());
  65519. }
  65520. return $buffer;
  65521. }
  65522. }
  65523. <?php
  65524. declare (strict_types=1);
  65525. /*
  65526. * This file is part of PHPUnit.
  65527. *
  65528. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65529. *
  65530. * For the full copyright and license information, please view the LICENSE
  65531. * file that was distributed with this source code.
  65532. */
  65533. namespace PHPUnit\Logging\TestDox;
  65534. use function sprintf;
  65535. /**
  65536. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65537. *
  65538. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65539. */
  65540. final class HtmlRenderer
  65541. {
  65542. /**
  65543. * @var string
  65544. */
  65545. private const PAGE_HEADER = <<<'EOT'
  65546. <!doctype html>
  65547. <html lang="en">
  65548. <head>
  65549. <meta charset="utf-8"/>
  65550. <title>Test Documentation</title>
  65551. <style>
  65552. body {
  65553. text-rendering: optimizeLegibility;
  65554. font-family: Source SansSerif Pro, Arial, sans-serif;
  65555. font-variant-ligatures: common-ligatures;
  65556. font-kerning: normal;
  65557. margin-left: 2rem;
  65558. background-color: #fff;
  65559. color: #000;
  65560. }
  65561. body > ul > li {
  65562. font-size: larger;
  65563. }
  65564. h2 {
  65565. font-size: larger;
  65566. text-decoration-line: underline;
  65567. text-decoration-thickness: 2px;
  65568. margin: 0;
  65569. padding: 0.5rem 0;
  65570. }
  65571. ul {
  65572. list-style: none;
  65573. margin: 0 0 2rem;
  65574. padding: 0 0 0 1rem;
  65575. text-indent: -1rem;
  65576. }
  65577. .success:before {
  65578. color: #4e9a06;
  65579. content: '✓';
  65580. padding-right: 0.5rem;
  65581. }
  65582. .defect {
  65583. color: #a40000;
  65584. }
  65585. .defect:before {
  65586. color: #a40000;
  65587. content: '✗';
  65588. padding-right: 0.5rem;
  65589. }
  65590. </style>
  65591. </head>
  65592. <body>
  65593. EOT;
  65594. /**
  65595. * @var string
  65596. */
  65597. private const CLASS_HEADER = <<<'EOT'
  65598. <h2>%s</h2>
  65599. <ul>
  65600. EOT;
  65601. /**
  65602. * @var string
  65603. */
  65604. private const CLASS_FOOTER = <<<'EOT'
  65605. </ul>
  65606. EOT;
  65607. /**
  65608. * @var string
  65609. */
  65610. private const PAGE_FOOTER = <<<'EOT'
  65611. </body>
  65612. </html>
  65613. EOT;
  65614. /**
  65615. * @psalm-param array<string, TestResultCollection> $tests
  65616. */
  65617. public function render(array $tests): string
  65618. {
  65619. $buffer = self::PAGE_HEADER;
  65620. foreach ($tests as $prettifiedClassName => $_tests) {
  65621. $buffer .= sprintf(self::CLASS_HEADER, $prettifiedClassName);
  65622. foreach ($this->reduce($_tests) as $prettifiedMethodName => $outcome) {
  65623. $buffer .= sprintf(" <li class=\"%s\">%s</li>\n", $outcome, $prettifiedMethodName);
  65624. }
  65625. $buffer .= self::CLASS_FOOTER;
  65626. }
  65627. return $buffer . self::PAGE_FOOTER;
  65628. }
  65629. /**
  65630. * @psalm-return array<string, 'success'|'defect'>
  65631. */
  65632. private function reduce(\PHPUnit\Logging\TestDox\TestResultCollection $tests): array
  65633. {
  65634. $result = [];
  65635. foreach ($tests as $test) {
  65636. $prettifiedMethodName = $test->test()->testDox()->prettifiedMethodName();
  65637. if (!isset($result[$prettifiedMethodName])) {
  65638. $result[$prettifiedMethodName] = $test->status()->isSuccess() ? 'success' : 'defect';
  65639. continue;
  65640. }
  65641. if ($test->status()->isSuccess()) {
  65642. continue;
  65643. }
  65644. $result[$prettifiedMethodName] = 'defect';
  65645. }
  65646. return $result;
  65647. }
  65648. }
  65649. <?php
  65650. declare (strict_types=1);
  65651. /*
  65652. * This file is part of PHPUnit.
  65653. *
  65654. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65655. *
  65656. * For the full copyright and license information, please view the LICENSE
  65657. * file that was distributed with this source code.
  65658. */
  65659. namespace PHPUnit\Logging\TestDox;
  65660. use function array_key_exists;
  65661. use function array_keys;
  65662. use function array_map;
  65663. use function array_pop;
  65664. use function array_values;
  65665. use function assert;
  65666. use function class_exists;
  65667. use function explode;
  65668. use function gettype;
  65669. use function implode;
  65670. use function is_bool;
  65671. use function is_float;
  65672. use function is_int;
  65673. use function is_object;
  65674. use function is_scalar;
  65675. use function method_exists;
  65676. use function preg_quote;
  65677. use function preg_replace;
  65678. use function rtrim;
  65679. use function sprintf;
  65680. use function str_contains;
  65681. use function str_ends_with;
  65682. use function str_replace;
  65683. use function str_starts_with;
  65684. use function strlen;
  65685. use function strtolower;
  65686. use function strtoupper;
  65687. use function substr;
  65688. use function trim;
  65689. use PHPUnit\Framework\TestCase;
  65690. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  65691. use PHPUnit\Metadata\TestDox;
  65692. use PHPUnit\Util\Color;
  65693. use ReflectionEnum;
  65694. use ReflectionMethod;
  65695. use ReflectionObject;
  65696. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  65697. /**
  65698. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65699. *
  65700. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65701. */
  65702. final class NamePrettifier
  65703. {
  65704. /**
  65705. * @psalm-var array<string, int>
  65706. */
  65707. private static array $strings = [];
  65708. /**
  65709. * @psalm-param class-string $className
  65710. */
  65711. public function prettifyTestClassName(string $className): string
  65712. {
  65713. if (class_exists($className)) {
  65714. $classLevelTestDox = MetadataRegistry::parser()->forClass($className)->isTestDox();
  65715. if ($classLevelTestDox->isNotEmpty()) {
  65716. $classLevelTestDox = $classLevelTestDox->asArray()[0];
  65717. assert($classLevelTestDox instanceof TestDox);
  65718. return $classLevelTestDox->text();
  65719. }
  65720. }
  65721. $parts = explode('\\', $className);
  65722. $className = array_pop($parts);
  65723. if (str_ends_with($className, 'Test')) {
  65724. $className = substr($className, 0, strlen($className) - strlen('Test'));
  65725. }
  65726. if (str_starts_with($className, 'Tests')) {
  65727. $className = substr($className, strlen('Tests'));
  65728. } elseif (str_starts_with($className, 'Test')) {
  65729. $className = substr($className, strlen('Test'));
  65730. }
  65731. if (empty($className)) {
  65732. $className = 'UnnamedTests';
  65733. }
  65734. if (!empty($parts)) {
  65735. $parts[] = $className;
  65736. $fullyQualifiedName = implode('\\', $parts);
  65737. } else {
  65738. $fullyQualifiedName = $className;
  65739. }
  65740. $result = preg_replace('/(?<=[[:lower:]])(?=[[:upper:]])/u', ' ', $className);
  65741. if ($fullyQualifiedName !== $className) {
  65742. return $result . ' (' . $fullyQualifiedName . ')';
  65743. }
  65744. return $result;
  65745. }
  65746. // NOTE: this method is on a hot path and very performance sensitive. change with care.
  65747. public function prettifyTestMethodName(string $name): string
  65748. {
  65749. if ($name === '') {
  65750. return '';
  65751. }
  65752. $string = rtrim($name, '0123456789');
  65753. if (array_key_exists($string, self::$strings)) {
  65754. $name = $string;
  65755. } elseif ($string === $name) {
  65756. self::$strings[$string] = 1;
  65757. }
  65758. if (str_starts_with($name, 'test_')) {
  65759. $name = substr($name, 5);
  65760. } elseif (str_starts_with($name, 'test')) {
  65761. $name = substr($name, 4);
  65762. }
  65763. if ($name === '') {
  65764. return '';
  65765. }
  65766. $name[0] = strtoupper($name[0]);
  65767. $noUnderscore = str_replace('_', ' ', $name);
  65768. if ($noUnderscore !== $name) {
  65769. return trim($noUnderscore);
  65770. }
  65771. $wasNumeric = \false;
  65772. $buffer = '';
  65773. $len = strlen($name);
  65774. for ($i = 0; $i < $len; $i++) {
  65775. if ($i > 0 && $name[$i] >= 'A' && $name[$i] <= 'Z') {
  65776. $buffer .= ' ' . strtolower($name[$i]);
  65777. } else {
  65778. $isNumeric = $name[$i] >= '0' && $name[$i] <= '9';
  65779. if (!$wasNumeric && $isNumeric) {
  65780. $buffer .= ' ';
  65781. $wasNumeric = \true;
  65782. }
  65783. if ($wasNumeric && !$isNumeric) {
  65784. $wasNumeric = \false;
  65785. }
  65786. $buffer .= $name[$i];
  65787. }
  65788. }
  65789. return $buffer;
  65790. }
  65791. public function prettifyTestCase(TestCase $test, bool $colorize): string
  65792. {
  65793. $annotationWithPlaceholders = \false;
  65794. $methodLevelTestDox = MetadataRegistry::parser()->forMethod($test::class, $test->name())->isTestDox()->isMethodLevel();
  65795. if ($methodLevelTestDox->isNotEmpty()) {
  65796. $methodLevelTestDox = $methodLevelTestDox->asArray()[0];
  65797. assert($methodLevelTestDox instanceof TestDox);
  65798. $result = $methodLevelTestDox->text();
  65799. if (str_contains($result, '$')) {
  65800. $annotation = $result;
  65801. $providedData = $this->mapTestMethodParameterNamesToProvidedDataValues($test, $colorize);
  65802. $variables = array_map(static fn(string $variable): string => sprintf('/%s(?=\b)/', preg_quote($variable, '/')), array_keys($providedData));
  65803. $result = preg_replace($variables, $providedData, $annotation);
  65804. $annotationWithPlaceholders = \true;
  65805. }
  65806. } else {
  65807. $result = $this->prettifyTestMethodName($test->name());
  65808. }
  65809. if (!$annotationWithPlaceholders && $test->usesDataProvider()) {
  65810. $result .= $this->prettifyDataSet($test, $colorize);
  65811. }
  65812. return $result;
  65813. }
  65814. public function prettifyDataSet(TestCase $test, bool $colorize): string
  65815. {
  65816. if (!$colorize) {
  65817. return $test->dataSetAsString();
  65818. }
  65819. if (is_int($test->dataName())) {
  65820. return Color::dim(' with data set ') . Color::colorize('fg-cyan', (string) $test->dataName());
  65821. }
  65822. return Color::dim(' with ') . Color::colorize('fg-cyan', Color::visualizeWhitespace($test->dataName()));
  65823. }
  65824. private function mapTestMethodParameterNamesToProvidedDataValues(TestCase $test, bool $colorize): array
  65825. {
  65826. assert(method_exists($test, $test->name()));
  65827. /** @noinspection PhpUnhandledExceptionInspection */
  65828. $reflector = new ReflectionMethod($test::class, $test->name());
  65829. $providedData = [];
  65830. $providedDataValues = array_values($test->providedData());
  65831. $i = 0;
  65832. $providedData['$_dataName'] = $test->dataName();
  65833. foreach ($reflector->getParameters() as $parameter) {
  65834. if (!array_key_exists($i, $providedDataValues) && $parameter->isDefaultValueAvailable()) {
  65835. $providedDataValues[$i] = $parameter->getDefaultValue();
  65836. }
  65837. $value = $providedDataValues[$i++] ?? null;
  65838. if (is_object($value)) {
  65839. $value = $this->objectToString($value);
  65840. }
  65841. if (!is_scalar($value)) {
  65842. $value = gettype($value);
  65843. if ($value === 'NULL') {
  65844. $value = 'null';
  65845. }
  65846. }
  65847. if (is_bool($value) || is_int($value) || is_float($value)) {
  65848. $value = (new Exporter())->export($value);
  65849. }
  65850. if ($value === '') {
  65851. if ($colorize) {
  65852. $value = Color::colorize('dim,underlined', 'empty');
  65853. } else {
  65854. $value = "''";
  65855. }
  65856. }
  65857. $providedData['$' . $parameter->getName()] = str_replace('$', '\$', $value);
  65858. }
  65859. if ($colorize) {
  65860. $providedData = array_map(static fn($value) => Color::colorize('fg-cyan', Color::visualizeWhitespace((string) $value, \true)), $providedData);
  65861. }
  65862. return $providedData;
  65863. }
  65864. /**
  65865. * @return non-empty-string
  65866. */
  65867. private function objectToString(object $value): string
  65868. {
  65869. $reflector = new ReflectionObject($value);
  65870. if ($reflector->isEnum()) {
  65871. $enumReflector = new ReflectionEnum($value);
  65872. if ($enumReflector->isBacked()) {
  65873. return $value->value;
  65874. }
  65875. return $value->name;
  65876. }
  65877. if ($reflector->hasMethod('__toString')) {
  65878. return $value->__toString();
  65879. }
  65880. return $value::class;
  65881. }
  65882. }
  65883. <?php
  65884. declare (strict_types=1);
  65885. /*
  65886. * This file is part of PHPUnit.
  65887. *
  65888. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65889. *
  65890. * For the full copyright and license information, please view the LICENSE
  65891. * file that was distributed with this source code.
  65892. */
  65893. namespace PHPUnit\Logging\TestDox;
  65894. use function sprintf;
  65895. /**
  65896. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65897. *
  65898. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65899. */
  65900. final class PlainTextRenderer
  65901. {
  65902. /**
  65903. * @psalm-param array<string, TestResultCollection> $tests
  65904. */
  65905. public function render(array $tests): string
  65906. {
  65907. $buffer = '';
  65908. foreach ($tests as $prettifiedClassName => $_tests) {
  65909. $buffer .= $prettifiedClassName . "\n";
  65910. foreach ($this->reduce($_tests) as $prettifiedMethodName => $outcome) {
  65911. $buffer .= sprintf(' [%s] %s' . "\n", $outcome, $prettifiedMethodName);
  65912. }
  65913. $buffer .= "\n";
  65914. }
  65915. return $buffer;
  65916. }
  65917. /**
  65918. * @psalm-return array<string, 'x'|' '>
  65919. */
  65920. private function reduce(\PHPUnit\Logging\TestDox\TestResultCollection $tests): array
  65921. {
  65922. $result = [];
  65923. foreach ($tests as $test) {
  65924. $prettifiedMethodName = $test->test()->testDox()->prettifiedMethodName();
  65925. $success = \true;
  65926. if ($test->status()->isError() || $test->status()->isFailure() || $test->status()->isIncomplete() || $test->status()->isSkipped()) {
  65927. $success = \false;
  65928. }
  65929. if (!isset($result[$prettifiedMethodName])) {
  65930. $result[$prettifiedMethodName] = $success ? 'x' : ' ';
  65931. continue;
  65932. }
  65933. if ($success) {
  65934. continue;
  65935. }
  65936. $result[$prettifiedMethodName] = ' ';
  65937. }
  65938. return $result;
  65939. }
  65940. }
  65941. <?php
  65942. declare (strict_types=1);
  65943. /*
  65944. * This file is part of PHPUnit.
  65945. *
  65946. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65947. *
  65948. * For the full copyright and license information, please view the LICENSE
  65949. * file that was distributed with this source code.
  65950. */
  65951. namespace PHPUnit\Logging\TestDox;
  65952. /**
  65953. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65954. *
  65955. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65956. */
  65957. abstract class Subscriber
  65958. {
  65959. private readonly \PHPUnit\Logging\TestDox\TestResultCollector $collector;
  65960. public function __construct(\PHPUnit\Logging\TestDox\TestResultCollector $collector)
  65961. {
  65962. $this->collector = $collector;
  65963. }
  65964. protected function collector(): \PHPUnit\Logging\TestDox\TestResultCollector
  65965. {
  65966. return $this->collector;
  65967. }
  65968. }
  65969. <?php
  65970. declare (strict_types=1);
  65971. /*
  65972. * This file is part of PHPUnit.
  65973. *
  65974. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  65975. *
  65976. * For the full copyright and license information, please view the LICENSE
  65977. * file that was distributed with this source code.
  65978. */
  65979. namespace PHPUnit\Logging\TestDox;
  65980. use PHPUnit\Event\Test\ConsideredRisky;
  65981. use PHPUnit\Event\Test\ConsideredRiskySubscriber;
  65982. /**
  65983. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  65984. *
  65985. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  65986. */
  65987. final class TestConsideredRiskySubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements ConsideredRiskySubscriber
  65988. {
  65989. public function notify(ConsideredRisky $event): void
  65990. {
  65991. $this->collector()->testConsideredRisky($event);
  65992. }
  65993. }
  65994. <?php
  65995. declare (strict_types=1);
  65996. /*
  65997. * This file is part of PHPUnit.
  65998. *
  65999. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66000. *
  66001. * For the full copyright and license information, please view the LICENSE
  66002. * file that was distributed with this source code.
  66003. */
  66004. namespace PHPUnit\Logging\TestDox;
  66005. use PHPUnit\Event\Test\Errored;
  66006. use PHPUnit\Event\Test\ErroredSubscriber;
  66007. /**
  66008. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66009. *
  66010. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66011. */
  66012. final class TestErroredSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements ErroredSubscriber
  66013. {
  66014. public function notify(Errored $event): void
  66015. {
  66016. $this->collector()->testErrored($event);
  66017. }
  66018. }
  66019. <?php
  66020. declare (strict_types=1);
  66021. /*
  66022. * This file is part of PHPUnit.
  66023. *
  66024. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66025. *
  66026. * For the full copyright and license information, please view the LICENSE
  66027. * file that was distributed with this source code.
  66028. */
  66029. namespace PHPUnit\Logging\TestDox;
  66030. use PHPUnit\Event\Test\Failed;
  66031. use PHPUnit\Event\Test\FailedSubscriber;
  66032. /**
  66033. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66034. *
  66035. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66036. */
  66037. final class TestFailedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements FailedSubscriber
  66038. {
  66039. public function notify(Failed $event): void
  66040. {
  66041. $this->collector()->testFailed($event);
  66042. }
  66043. }
  66044. <?php
  66045. declare (strict_types=1);
  66046. /*
  66047. * This file is part of PHPUnit.
  66048. *
  66049. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66050. *
  66051. * For the full copyright and license information, please view the LICENSE
  66052. * file that was distributed with this source code.
  66053. */
  66054. namespace PHPUnit\Logging\TestDox;
  66055. use PHPUnit\Event\InvalidArgumentException;
  66056. use PHPUnit\Event\Test\Finished;
  66057. use PHPUnit\Event\Test\FinishedSubscriber;
  66058. /**
  66059. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66060. *
  66061. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66062. */
  66063. final class TestFinishedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements FinishedSubscriber
  66064. {
  66065. /**
  66066. * @throws InvalidArgumentException
  66067. */
  66068. public function notify(Finished $event): void
  66069. {
  66070. $this->collector()->testFinished($event);
  66071. }
  66072. }
  66073. <?php
  66074. declare (strict_types=1);
  66075. /*
  66076. * This file is part of PHPUnit.
  66077. *
  66078. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66079. *
  66080. * For the full copyright and license information, please view the LICENSE
  66081. * file that was distributed with this source code.
  66082. */
  66083. namespace PHPUnit\Logging\TestDox;
  66084. use PHPUnit\Event\Test\MarkedIncomplete;
  66085. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  66086. /**
  66087. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66088. *
  66089. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66090. */
  66091. final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements MarkedIncompleteSubscriber
  66092. {
  66093. public function notify(MarkedIncomplete $event): void
  66094. {
  66095. $this->collector()->testMarkedIncomplete($event);
  66096. }
  66097. }
  66098. <?php
  66099. declare (strict_types=1);
  66100. /*
  66101. * This file is part of PHPUnit.
  66102. *
  66103. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66104. *
  66105. * For the full copyright and license information, please view the LICENSE
  66106. * file that was distributed with this source code.
  66107. */
  66108. namespace PHPUnit\Logging\TestDox;
  66109. use PHPUnit\Event\Test\Passed;
  66110. use PHPUnit\Event\Test\PassedSubscriber;
  66111. /**
  66112. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66113. *
  66114. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66115. */
  66116. final class TestPassedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PassedSubscriber
  66117. {
  66118. public function notify(Passed $event): void
  66119. {
  66120. $this->collector()->testPassed($event);
  66121. }
  66122. }
  66123. <?php
  66124. declare (strict_types=1);
  66125. /*
  66126. * This file is part of PHPUnit.
  66127. *
  66128. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66129. *
  66130. * For the full copyright and license information, please view the LICENSE
  66131. * file that was distributed with this source code.
  66132. */
  66133. namespace PHPUnit\Logging\TestDox;
  66134. use PHPUnit\Event\Test\Prepared;
  66135. use PHPUnit\Event\Test\PreparedSubscriber;
  66136. /**
  66137. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66138. *
  66139. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66140. */
  66141. final class TestPreparedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PreparedSubscriber
  66142. {
  66143. public function notify(Prepared $event): void
  66144. {
  66145. $this->collector()->testPrepared($event);
  66146. }
  66147. }
  66148. <?php
  66149. declare (strict_types=1);
  66150. /*
  66151. * This file is part of PHPUnit.
  66152. *
  66153. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66154. *
  66155. * For the full copyright and license information, please view the LICENSE
  66156. * file that was distributed with this source code.
  66157. */
  66158. namespace PHPUnit\Logging\TestDox;
  66159. use PHPUnit\Event\Test\Skipped;
  66160. use PHPUnit\Event\Test\SkippedSubscriber;
  66161. /**
  66162. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66163. *
  66164. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66165. */
  66166. final class TestSkippedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements SkippedSubscriber
  66167. {
  66168. public function notify(Skipped $event): void
  66169. {
  66170. $this->collector()->testSkipped($event);
  66171. }
  66172. }
  66173. <?php
  66174. declare (strict_types=1);
  66175. /*
  66176. * This file is part of PHPUnit.
  66177. *
  66178. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66179. *
  66180. * For the full copyright and license information, please view the LICENSE
  66181. * file that was distributed with this source code.
  66182. */
  66183. namespace PHPUnit\Logging\TestDox;
  66184. use PHPUnit\Event\Test\DeprecationTriggered;
  66185. use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
  66186. /**
  66187. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66188. *
  66189. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66190. */
  66191. final class TestTriggeredDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements DeprecationTriggeredSubscriber
  66192. {
  66193. public function notify(DeprecationTriggered $event): void
  66194. {
  66195. $this->collector()->testTriggeredDeprecation($event);
  66196. }
  66197. }
  66198. <?php
  66199. declare (strict_types=1);
  66200. /*
  66201. * This file is part of PHPUnit.
  66202. *
  66203. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66204. *
  66205. * For the full copyright and license information, please view the LICENSE
  66206. * file that was distributed with this source code.
  66207. */
  66208. namespace PHPUnit\Logging\TestDox;
  66209. use PHPUnit\Event\Test\NoticeTriggered;
  66210. use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
  66211. /**
  66212. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66213. *
  66214. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66215. */
  66216. final class TestTriggeredNoticeSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements NoticeTriggeredSubscriber
  66217. {
  66218. public function notify(NoticeTriggered $event): void
  66219. {
  66220. $this->collector()->testTriggeredNotice($event);
  66221. }
  66222. }
  66223. <?php
  66224. declare (strict_types=1);
  66225. /*
  66226. * This file is part of PHPUnit.
  66227. *
  66228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66229. *
  66230. * For the full copyright and license information, please view the LICENSE
  66231. * file that was distributed with this source code.
  66232. */
  66233. namespace PHPUnit\Logging\TestDox;
  66234. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  66235. use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
  66236. /**
  66237. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66238. *
  66239. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66240. */
  66241. final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpDeprecationTriggeredSubscriber
  66242. {
  66243. public function notify(PhpDeprecationTriggered $event): void
  66244. {
  66245. $this->collector()->testTriggeredPhpDeprecation($event);
  66246. }
  66247. }
  66248. <?php
  66249. declare (strict_types=1);
  66250. /*
  66251. * This file is part of PHPUnit.
  66252. *
  66253. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66254. *
  66255. * For the full copyright and license information, please view the LICENSE
  66256. * file that was distributed with this source code.
  66257. */
  66258. namespace PHPUnit\Logging\TestDox;
  66259. use PHPUnit\Event\Test\PhpNoticeTriggered;
  66260. use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
  66261. /**
  66262. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66263. *
  66264. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66265. */
  66266. final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpNoticeTriggeredSubscriber
  66267. {
  66268. public function notify(PhpNoticeTriggered $event): void
  66269. {
  66270. $this->collector()->testTriggeredPhpNotice($event);
  66271. }
  66272. }
  66273. <?php
  66274. declare (strict_types=1);
  66275. /*
  66276. * This file is part of PHPUnit.
  66277. *
  66278. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66279. *
  66280. * For the full copyright and license information, please view the LICENSE
  66281. * file that was distributed with this source code.
  66282. */
  66283. namespace PHPUnit\Logging\TestDox;
  66284. use PHPUnit\Event\Test\PhpWarningTriggered;
  66285. use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
  66286. /**
  66287. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66288. *
  66289. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66290. */
  66291. final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpWarningTriggeredSubscriber
  66292. {
  66293. public function notify(PhpWarningTriggered $event): void
  66294. {
  66295. $this->collector()->testTriggeredPhpWarning($event);
  66296. }
  66297. }
  66298. <?php
  66299. declare (strict_types=1);
  66300. /*
  66301. * This file is part of PHPUnit.
  66302. *
  66303. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66304. *
  66305. * For the full copyright and license information, please view the LICENSE
  66306. * file that was distributed with this source code.
  66307. */
  66308. namespace PHPUnit\Logging\TestDox;
  66309. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  66310. use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
  66311. /**
  66312. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66313. *
  66314. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66315. */
  66316. final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitDeprecationTriggeredSubscriber
  66317. {
  66318. public function notify(PhpunitDeprecationTriggered $event): void
  66319. {
  66320. $this->collector()->testTriggeredPhpunitDeprecation($event);
  66321. }
  66322. }
  66323. <?php
  66324. declare (strict_types=1);
  66325. /*
  66326. * This file is part of PHPUnit.
  66327. *
  66328. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66329. *
  66330. * For the full copyright and license information, please view the LICENSE
  66331. * file that was distributed with this source code.
  66332. */
  66333. namespace PHPUnit\Logging\TestDox;
  66334. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  66335. use PHPUnit\Event\Test\PhpunitErrorTriggeredSubscriber;
  66336. /**
  66337. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66338. *
  66339. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66340. */
  66341. final class TestTriggeredPhpunitErrorSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitErrorTriggeredSubscriber
  66342. {
  66343. public function notify(PhpunitErrorTriggered $event): void
  66344. {
  66345. $this->collector()->testTriggeredPhpunitError($event);
  66346. }
  66347. }
  66348. <?php
  66349. declare (strict_types=1);
  66350. /*
  66351. * This file is part of PHPUnit.
  66352. *
  66353. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66354. *
  66355. * For the full copyright and license information, please view the LICENSE
  66356. * file that was distributed with this source code.
  66357. */
  66358. namespace PHPUnit\Logging\TestDox;
  66359. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  66360. use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
  66361. /**
  66362. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66363. *
  66364. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66365. */
  66366. final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitWarningTriggeredSubscriber
  66367. {
  66368. public function notify(PhpunitWarningTriggered $event): void
  66369. {
  66370. $this->collector()->testTriggeredPhpunitWarning($event);
  66371. }
  66372. }
  66373. <?php
  66374. declare (strict_types=1);
  66375. /*
  66376. * This file is part of PHPUnit.
  66377. *
  66378. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66379. *
  66380. * For the full copyright and license information, please view the LICENSE
  66381. * file that was distributed with this source code.
  66382. */
  66383. namespace PHPUnit\Logging\TestDox;
  66384. use PHPUnit\Event\Test\WarningTriggered;
  66385. use PHPUnit\Event\Test\WarningTriggeredSubscriber;
  66386. /**
  66387. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66388. *
  66389. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66390. */
  66391. final class TestTriggeredWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements WarningTriggeredSubscriber
  66392. {
  66393. public function notify(WarningTriggered $event): void
  66394. {
  66395. $this->collector()->testTriggeredWarning($event);
  66396. }
  66397. }
  66398. <?php
  66399. declare (strict_types=1);
  66400. /*
  66401. * This file is part of PHPUnit.
  66402. *
  66403. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66404. *
  66405. * For the full copyright and license information, please view the LICENSE
  66406. * file that was distributed with this source code.
  66407. */
  66408. namespace PHPUnit\Logging\TestDox;
  66409. use PHPUnit\Event\Code\TestMethod;
  66410. use PHPUnit\Event\Code\Throwable;
  66411. use PHPUnit\Framework\TestStatus\TestStatus;
  66412. /**
  66413. * @psalm-immutable
  66414. *
  66415. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66416. *
  66417. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66418. */
  66419. final class TestResult
  66420. {
  66421. private readonly TestMethod $test;
  66422. private readonly TestStatus $status;
  66423. private readonly ?Throwable $throwable;
  66424. public function __construct(TestMethod $test, TestStatus $status, ?Throwable $throwable)
  66425. {
  66426. $this->test = $test;
  66427. $this->status = $status;
  66428. $this->throwable = $throwable;
  66429. }
  66430. public function test(): TestMethod
  66431. {
  66432. return $this->test;
  66433. }
  66434. public function status(): TestStatus
  66435. {
  66436. return $this->status;
  66437. }
  66438. /**
  66439. * @psalm-assert-if-true !null $this->throwable
  66440. */
  66441. public function hasThrowable(): bool
  66442. {
  66443. return $this->throwable !== null;
  66444. }
  66445. public function throwable(): ?Throwable
  66446. {
  66447. return $this->throwable;
  66448. }
  66449. }
  66450. <?php
  66451. declare (strict_types=1);
  66452. /*
  66453. * This file is part of PHPUnit.
  66454. *
  66455. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66456. *
  66457. * For the full copyright and license information, please view the LICENSE
  66458. * file that was distributed with this source code.
  66459. */
  66460. namespace PHPUnit\Logging\TestDox;
  66461. use IteratorAggregate;
  66462. /**
  66463. * @template-implements IteratorAggregate<int, TestResult>
  66464. *
  66465. * @psalm-immutable
  66466. *
  66467. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66468. *
  66469. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66470. */
  66471. final class TestResultCollection implements IteratorAggregate
  66472. {
  66473. /**
  66474. * @psalm-var list<TestResult>
  66475. */
  66476. private readonly array $testResults;
  66477. /**
  66478. * @psalm-param list<TestResult> $testResults
  66479. */
  66480. public static function fromArray(array $testResults): self
  66481. {
  66482. return new self(...$testResults);
  66483. }
  66484. private function __construct(\PHPUnit\Logging\TestDox\TestResult ...$testResults)
  66485. {
  66486. $this->testResults = $testResults;
  66487. }
  66488. /**
  66489. * @psalm-return list<TestResult>
  66490. */
  66491. public function asArray(): array
  66492. {
  66493. return $this->testResults;
  66494. }
  66495. public function getIterator(): \PHPUnit\Logging\TestDox\TestResultCollectionIterator
  66496. {
  66497. return new \PHPUnit\Logging\TestDox\TestResultCollectionIterator($this);
  66498. }
  66499. }
  66500. <?php
  66501. declare (strict_types=1);
  66502. /*
  66503. * This file is part of PHPUnit.
  66504. *
  66505. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66506. *
  66507. * For the full copyright and license information, please view the LICENSE
  66508. * file that was distributed with this source code.
  66509. */
  66510. namespace PHPUnit\Logging\TestDox;
  66511. use function count;
  66512. use Iterator;
  66513. /**
  66514. * @template-implements Iterator<int, TestResult>
  66515. *
  66516. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66517. *
  66518. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66519. */
  66520. final class TestResultCollectionIterator implements Iterator
  66521. {
  66522. /**
  66523. * @psalm-var list<TestResult>
  66524. */
  66525. private readonly array $testResults;
  66526. private int $position = 0;
  66527. public function __construct(\PHPUnit\Logging\TestDox\TestResultCollection $testResults)
  66528. {
  66529. $this->testResults = $testResults->asArray();
  66530. }
  66531. public function rewind(): void
  66532. {
  66533. $this->position = 0;
  66534. }
  66535. public function valid(): bool
  66536. {
  66537. return $this->position < count($this->testResults);
  66538. }
  66539. public function key(): int
  66540. {
  66541. return $this->position;
  66542. }
  66543. public function current(): \PHPUnit\Logging\TestDox\TestResult
  66544. {
  66545. return $this->testResults[$this->position];
  66546. }
  66547. public function next(): void
  66548. {
  66549. $this->position++;
  66550. }
  66551. }
  66552. <?php
  66553. declare (strict_types=1);
  66554. /*
  66555. * This file is part of PHPUnit.
  66556. *
  66557. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66558. *
  66559. * For the full copyright and license information, please view the LICENSE
  66560. * file that was distributed with this source code.
  66561. */
  66562. namespace PHPUnit\Logging\TestDox;
  66563. use function array_keys;
  66564. use function array_merge;
  66565. use function assert;
  66566. use function is_subclass_of;
  66567. use function ksort;
  66568. use function uksort;
  66569. use function usort;
  66570. use PHPUnit\Event\Code\TestMethod;
  66571. use PHPUnit\Event\Code\Throwable;
  66572. use PHPUnit\Event\EventFacadeIsSealedException;
  66573. use PHPUnit\Event\Facade;
  66574. use PHPUnit\Event\InvalidArgumentException;
  66575. use PHPUnit\Event\Test\ConsideredRisky;
  66576. use PHPUnit\Event\Test\DeprecationTriggered;
  66577. use PHPUnit\Event\Test\Errored;
  66578. use PHPUnit\Event\Test\Failed;
  66579. use PHPUnit\Event\Test\Finished;
  66580. use PHPUnit\Event\Test\MarkedIncomplete;
  66581. use PHPUnit\Event\Test\NoticeTriggered;
  66582. use PHPUnit\Event\Test\Passed;
  66583. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  66584. use PHPUnit\Event\Test\PhpNoticeTriggered;
  66585. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  66586. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  66587. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  66588. use PHPUnit\Event\Test\PhpWarningTriggered;
  66589. use PHPUnit\Event\Test\Prepared;
  66590. use PHPUnit\Event\Test\Skipped;
  66591. use PHPUnit\Event\Test\WarningTriggered;
  66592. use PHPUnit\Event\UnknownSubscriberTypeException;
  66593. use PHPUnit\Framework\TestStatus\TestStatus;
  66594. use PHPUnit\Logging\TestDox\TestResult as TestDoxTestMethod;
  66595. use PHPUnit\TextUI\Configuration\Source;
  66596. use PHPUnit\TextUI\Configuration\SourceFilter;
  66597. use ReflectionMethod;
  66598. /**
  66599. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66600. *
  66601. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66602. */
  66603. final class TestResultCollector
  66604. {
  66605. private readonly Source $source;
  66606. /**
  66607. * @psalm-var array<string, list<TestDoxTestMethod>>
  66608. */
  66609. private array $tests = [];
  66610. private ?TestStatus $status = null;
  66611. private ?Throwable $throwable = null;
  66612. private bool $prepared = \false;
  66613. /**
  66614. * @throws EventFacadeIsSealedException
  66615. * @throws UnknownSubscriberTypeException
  66616. */
  66617. public function __construct(Facade $facade, Source $source)
  66618. {
  66619. $this->source = $source;
  66620. $this->registerSubscribers($facade);
  66621. }
  66622. /**
  66623. * @psalm-return array<string, TestResultCollection>
  66624. */
  66625. public function testMethodsGroupedByClass(): array
  66626. {
  66627. $result = [];
  66628. foreach ($this->tests as $prettifiedClassName => $tests) {
  66629. $testsByDeclaringClass = [];
  66630. foreach ($tests as $test) {
  66631. $declaringClassName = (new ReflectionMethod($test->test()->className(), $test->test()->methodName()))->getDeclaringClass()->getName();
  66632. if (!isset($testsByDeclaringClass[$declaringClassName])) {
  66633. $testsByDeclaringClass[$declaringClassName] = [];
  66634. }
  66635. $testsByDeclaringClass[$declaringClassName][] = $test;
  66636. }
  66637. foreach (array_keys($testsByDeclaringClass) as $declaringClassName) {
  66638. usort($testsByDeclaringClass[$declaringClassName], static function (TestDoxTestMethod $a, TestDoxTestMethod $b): int {
  66639. return $a->test()->line() <=> $b->test()->line();
  66640. });
  66641. }
  66642. uksort(
  66643. $testsByDeclaringClass,
  66644. /**
  66645. * @psalm-param class-string $a
  66646. * @psalm-param class-string $b
  66647. */
  66648. static function (string $a, string $b): int {
  66649. if (is_subclass_of($b, $a)) {
  66650. return -1;
  66651. }
  66652. if (is_subclass_of($a, $b)) {
  66653. return 1;
  66654. }
  66655. return 0;
  66656. }
  66657. );
  66658. $tests = [];
  66659. foreach ($testsByDeclaringClass as $_tests) {
  66660. $tests = array_merge($tests, $_tests);
  66661. }
  66662. $result[$prettifiedClassName] = \PHPUnit\Logging\TestDox\TestResultCollection::fromArray($tests);
  66663. }
  66664. ksort($result);
  66665. return $result;
  66666. }
  66667. public function testPrepared(Prepared $event): void
  66668. {
  66669. if (!$event->test()->isTestMethod()) {
  66670. return;
  66671. }
  66672. $this->status = TestStatus::unknown();
  66673. $this->throwable = null;
  66674. $this->prepared = \true;
  66675. }
  66676. public function testErrored(Errored $event): void
  66677. {
  66678. if (!$event->test()->isTestMethod()) {
  66679. return;
  66680. }
  66681. $this->status = TestStatus::error($event->throwable()->message());
  66682. $this->throwable = $event->throwable();
  66683. if (!$this->prepared) {
  66684. $test = $event->test();
  66685. assert($test instanceof TestMethod);
  66686. $this->process($test);
  66687. }
  66688. }
  66689. public function testFailed(Failed $event): void
  66690. {
  66691. if (!$event->test()->isTestMethod()) {
  66692. return;
  66693. }
  66694. $this->status = TestStatus::failure($event->throwable()->message());
  66695. $this->throwable = $event->throwable();
  66696. }
  66697. public function testPassed(Passed $event): void
  66698. {
  66699. if (!$event->test()->isTestMethod()) {
  66700. return;
  66701. }
  66702. $this->updateTestStatus(TestStatus::success());
  66703. }
  66704. public function testSkipped(Skipped $event): void
  66705. {
  66706. if (!$event->test()->isTestMethod()) {
  66707. return;
  66708. }
  66709. $this->updateTestStatus(TestStatus::skipped($event->message()));
  66710. }
  66711. public function testMarkedIncomplete(MarkedIncomplete $event): void
  66712. {
  66713. if (!$event->test()->isTestMethod()) {
  66714. return;
  66715. }
  66716. $this->updateTestStatus(TestStatus::incomplete($event->throwable()->message()));
  66717. $this->throwable = $event->throwable();
  66718. }
  66719. public function testConsideredRisky(ConsideredRisky $event): void
  66720. {
  66721. if (!$event->test()->isTestMethod()) {
  66722. return;
  66723. }
  66724. $this->updateTestStatus(TestStatus::risky());
  66725. }
  66726. public function testTriggeredDeprecation(DeprecationTriggered $event): void
  66727. {
  66728. if (!$event->test()->isTestMethod()) {
  66729. return;
  66730. }
  66731. if ($event->ignoredByTest()) {
  66732. return;
  66733. }
  66734. if ($event->ignoredByBaseline()) {
  66735. return;
  66736. }
  66737. if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
  66738. return;
  66739. }
  66740. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66741. return;
  66742. }
  66743. $this->updateTestStatus(TestStatus::deprecation());
  66744. }
  66745. public function testTriggeredNotice(NoticeTriggered $event): void
  66746. {
  66747. if (!$event->test()->isTestMethod()) {
  66748. return;
  66749. }
  66750. if ($event->ignoredByBaseline()) {
  66751. return;
  66752. }
  66753. if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
  66754. return;
  66755. }
  66756. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66757. return;
  66758. }
  66759. $this->updateTestStatus(TestStatus::notice());
  66760. }
  66761. public function testTriggeredWarning(WarningTriggered $event): void
  66762. {
  66763. if (!$event->test()->isTestMethod()) {
  66764. return;
  66765. }
  66766. if ($event->ignoredByBaseline()) {
  66767. return;
  66768. }
  66769. if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
  66770. return;
  66771. }
  66772. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66773. return;
  66774. }
  66775. $this->updateTestStatus(TestStatus::warning());
  66776. }
  66777. public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
  66778. {
  66779. if (!$event->test()->isTestMethod()) {
  66780. return;
  66781. }
  66782. if ($event->ignoredByTest()) {
  66783. return;
  66784. }
  66785. if ($event->ignoredByBaseline()) {
  66786. return;
  66787. }
  66788. if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
  66789. return;
  66790. }
  66791. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66792. return;
  66793. }
  66794. $this->updateTestStatus(TestStatus::deprecation());
  66795. }
  66796. public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
  66797. {
  66798. if (!$event->test()->isTestMethod()) {
  66799. return;
  66800. }
  66801. if ($event->ignoredByBaseline()) {
  66802. return;
  66803. }
  66804. if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
  66805. return;
  66806. }
  66807. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66808. return;
  66809. }
  66810. $this->updateTestStatus(TestStatus::notice());
  66811. }
  66812. public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
  66813. {
  66814. if (!$event->test()->isTestMethod()) {
  66815. return;
  66816. }
  66817. if ($event->ignoredByBaseline()) {
  66818. return;
  66819. }
  66820. if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
  66821. return;
  66822. }
  66823. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  66824. return;
  66825. }
  66826. $this->updateTestStatus(TestStatus::warning());
  66827. }
  66828. public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event): void
  66829. {
  66830. if (!$event->test()->isTestMethod()) {
  66831. return;
  66832. }
  66833. $this->updateTestStatus(TestStatus::deprecation());
  66834. }
  66835. public function testTriggeredPhpunitError(PhpunitErrorTriggered $event): void
  66836. {
  66837. if (!$event->test()->isTestMethod()) {
  66838. return;
  66839. }
  66840. $this->updateTestStatus(TestStatus::error());
  66841. }
  66842. public function testTriggeredPhpunitWarning(PhpunitWarningTriggered $event): void
  66843. {
  66844. if (!$event->test()->isTestMethod()) {
  66845. return;
  66846. }
  66847. $this->updateTestStatus(TestStatus::warning());
  66848. }
  66849. /**
  66850. * @throws InvalidArgumentException
  66851. */
  66852. public function testFinished(Finished $event): void
  66853. {
  66854. if (!$event->test()->isTestMethod()) {
  66855. return;
  66856. }
  66857. $test = $event->test();
  66858. assert($test instanceof TestMethod);
  66859. $this->process($test);
  66860. $this->status = null;
  66861. $this->throwable = null;
  66862. $this->prepared = \false;
  66863. }
  66864. /**
  66865. * @throws EventFacadeIsSealedException
  66866. * @throws UnknownSubscriberTypeException
  66867. */
  66868. private function registerSubscribers(Facade $facade): void
  66869. {
  66870. $facade->registerSubscribers(new \PHPUnit\Logging\TestDox\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TestDox\TestErroredSubscriber($this), new \PHPUnit\Logging\TestDox\TestFailedSubscriber($this), new \PHPUnit\Logging\TestDox\TestFinishedSubscriber($this), new \PHPUnit\Logging\TestDox\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TestDox\TestPassedSubscriber($this), new \PHPUnit\Logging\TestDox\TestPreparedSubscriber($this), new \PHPUnit\Logging\TestDox\TestSkippedSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredNoticeSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitErrorSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredWarningSubscriber($this));
  66871. }
  66872. private function updateTestStatus(TestStatus $status): void
  66873. {
  66874. if ($this->status !== null && $this->status->isMoreImportantThan($status)) {
  66875. return;
  66876. }
  66877. $this->status = $status;
  66878. }
  66879. private function process(TestMethod $test): void
  66880. {
  66881. if (!isset($this->tests[$test->testDox()->prettifiedClassName()])) {
  66882. $this->tests[$test->testDox()->prettifiedClassName()] = [];
  66883. }
  66884. $this->tests[$test->testDox()->prettifiedClassName()][] = new TestDoxTestMethod($test, $this->status, $this->throwable);
  66885. }
  66886. }
  66887. <?php
  66888. declare (strict_types=1);
  66889. /*
  66890. * This file is part of PHPUnit.
  66891. *
  66892. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66893. *
  66894. * For the full copyright and license information, please view the LICENSE
  66895. * file that was distributed with this source code.
  66896. */
  66897. namespace PHPUnit\Metadata;
  66898. /**
  66899. * @psalm-immutable
  66900. *
  66901. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66902. */
  66903. final class After extends \PHPUnit\Metadata\Metadata
  66904. {
  66905. /**
  66906. * @psalm-assert-if-true After $this
  66907. */
  66908. public function isAfter(): bool
  66909. {
  66910. return \true;
  66911. }
  66912. }
  66913. <?php
  66914. declare (strict_types=1);
  66915. /*
  66916. * This file is part of PHPUnit.
  66917. *
  66918. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66919. *
  66920. * For the full copyright and license information, please view the LICENSE
  66921. * file that was distributed with this source code.
  66922. */
  66923. namespace PHPUnit\Metadata;
  66924. /**
  66925. * @psalm-immutable
  66926. *
  66927. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66928. */
  66929. final class AfterClass extends \PHPUnit\Metadata\Metadata
  66930. {
  66931. /**
  66932. * @psalm-assert-if-true AfterClass $this
  66933. */
  66934. public function isAfterClass(): bool
  66935. {
  66936. return \true;
  66937. }
  66938. }
  66939. <?php
  66940. declare (strict_types=1);
  66941. /*
  66942. * This file is part of PHPUnit.
  66943. *
  66944. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66945. *
  66946. * For the full copyright and license information, please view the LICENSE
  66947. * file that was distributed with this source code.
  66948. */
  66949. namespace PHPUnit\Metadata\Api;
  66950. use function array_unique;
  66951. use function array_values;
  66952. use function assert;
  66953. use function count;
  66954. use function interface_exists;
  66955. use function sprintf;
  66956. use function str_starts_with;
  66957. use PHPUnit\Framework\CodeCoverageException;
  66958. use PHPUnit\Framework\InvalidCoversTargetException;
  66959. use PHPUnit\Framework\TestSuite;
  66960. use PHPUnit\Metadata\Covers;
  66961. use PHPUnit\Metadata\CoversClass;
  66962. use PHPUnit\Metadata\CoversDefaultClass;
  66963. use PHPUnit\Metadata\CoversFunction;
  66964. use PHPUnit\Metadata\IgnoreClassForCodeCoverage;
  66965. use PHPUnit\Metadata\IgnoreFunctionForCodeCoverage;
  66966. use PHPUnit\Metadata\IgnoreMethodForCodeCoverage;
  66967. use PHPUnit\Metadata\Parser\Registry;
  66968. use PHPUnit\Metadata\Uses;
  66969. use PHPUnit\Metadata\UsesClass;
  66970. use PHPUnit\Metadata\UsesDefaultClass;
  66971. use PHPUnit\Metadata\UsesFunction;
  66972. use RecursiveIteratorIterator;
  66973. use PHPUnitPHAR\SebastianBergmann\CodeUnit\CodeUnitCollection;
  66974. use PHPUnitPHAR\SebastianBergmann\CodeUnit\Exception as CodeUnitException;
  66975. use PHPUnitPHAR\SebastianBergmann\CodeUnit\InvalidCodeUnitException;
  66976. use PHPUnitPHAR\SebastianBergmann\CodeUnit\Mapper;
  66977. /**
  66978. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  66979. *
  66980. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  66981. */
  66982. final class CodeCoverage
  66983. {
  66984. /**
  66985. * @psalm-param class-string $className
  66986. * @psalm-param non-empty-string $methodName
  66987. *
  66988. * @psalm-return array<string,list<int>>|false
  66989. *
  66990. * @throws CodeCoverageException
  66991. */
  66992. public function linesToBeCovered(string $className, string $methodName): array|false
  66993. {
  66994. if (!$this->shouldCodeCoverageBeCollectedFor($className, $methodName)) {
  66995. return \false;
  66996. }
  66997. $metadataForClass = Registry::parser()->forClass($className);
  66998. $classShortcut = null;
  66999. if ($metadataForClass->isCoversDefaultClass()->isNotEmpty()) {
  67000. if (count($metadataForClass->isCoversDefaultClass()) > 1) {
  67001. throw new CodeCoverageException(sprintf('More than one @coversDefaultClass annotation for class or interface "%s"', $className));
  67002. }
  67003. $metadata = $metadataForClass->isCoversDefaultClass()->asArray()[0];
  67004. assert($metadata instanceof CoversDefaultClass);
  67005. $classShortcut = $metadata->className();
  67006. }
  67007. $codeUnits = CodeUnitCollection::fromList();
  67008. $mapper = new Mapper();
  67009. foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
  67010. if (!$metadata->isCoversClass() && !$metadata->isCoversFunction() && !$metadata->isCovers()) {
  67011. continue;
  67012. }
  67013. assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction || $metadata instanceof Covers);
  67014. if ($metadata->isCoversClass() || $metadata->isCoversFunction()) {
  67015. $codeUnits = $codeUnits->mergeWith($this->mapToCodeUnits($metadata));
  67016. } elseif ($metadata->isCovers()) {
  67017. assert($metadata instanceof Covers);
  67018. $target = $metadata->target();
  67019. if (interface_exists($target)) {
  67020. throw new InvalidCoversTargetException(sprintf('Trying to @cover interface "%s".', $target));
  67021. }
  67022. if ($classShortcut !== null && str_starts_with($target, '::')) {
  67023. $target = $classShortcut . $target;
  67024. }
  67025. try {
  67026. $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target));
  67027. } catch (InvalidCodeUnitException $e) {
  67028. throw new InvalidCoversTargetException(sprintf('"@covers %s" is invalid', $target), $e->getCode(), $e);
  67029. }
  67030. }
  67031. }
  67032. return $mapper->codeUnitsToSourceLines($codeUnits);
  67033. }
  67034. /**
  67035. * @psalm-param class-string $className
  67036. * @psalm-param non-empty-string $methodName
  67037. *
  67038. * @psalm-return array<string,list<int>>
  67039. *
  67040. * @throws CodeCoverageException
  67041. */
  67042. public function linesToBeUsed(string $className, string $methodName): array
  67043. {
  67044. $metadataForClass = Registry::parser()->forClass($className);
  67045. $classShortcut = null;
  67046. if ($metadataForClass->isUsesDefaultClass()->isNotEmpty()) {
  67047. if (count($metadataForClass->isUsesDefaultClass()) > 1) {
  67048. throw new CodeCoverageException(sprintf('More than one @usesDefaultClass annotation for class or interface "%s"', $className));
  67049. }
  67050. $metadata = $metadataForClass->isUsesDefaultClass()->asArray()[0];
  67051. assert($metadata instanceof UsesDefaultClass);
  67052. $classShortcut = $metadata->className();
  67053. }
  67054. $codeUnits = CodeUnitCollection::fromList();
  67055. $mapper = new Mapper();
  67056. foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
  67057. if (!$metadata->isUsesClass() && !$metadata->isUsesFunction() && !$metadata->isUses()) {
  67058. continue;
  67059. }
  67060. assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction || $metadata instanceof Uses);
  67061. if ($metadata->isUsesClass() || $metadata->isUsesFunction()) {
  67062. $codeUnits = $codeUnits->mergeWith($this->mapToCodeUnits($metadata));
  67063. } elseif ($metadata->isUses()) {
  67064. assert($metadata instanceof Uses);
  67065. $target = $metadata->target();
  67066. if ($classShortcut !== null && str_starts_with($target, '::')) {
  67067. $target = $classShortcut . $target;
  67068. }
  67069. try {
  67070. $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target));
  67071. } catch (InvalidCodeUnitException $e) {
  67072. throw new InvalidCoversTargetException(sprintf('"@uses %s" is invalid', $target), $e->getCode(), $e);
  67073. }
  67074. }
  67075. }
  67076. return $mapper->codeUnitsToSourceLines($codeUnits);
  67077. }
  67078. /**
  67079. * @psalm-return array<string,list<int>>
  67080. */
  67081. public function linesToBeIgnored(TestSuite $testSuite): array
  67082. {
  67083. $codeUnits = CodeUnitCollection::fromList();
  67084. $mapper = new Mapper();
  67085. foreach ($this->testCaseClassesIn($testSuite) as $testCaseClassName) {
  67086. $codeUnits = $codeUnits->mergeWith($this->codeUnitsIgnoredBy($testCaseClassName));
  67087. }
  67088. return $mapper->codeUnitsToSourceLines($codeUnits);
  67089. }
  67090. /**
  67091. * @psalm-param class-string $className
  67092. * @psalm-param non-empty-string $methodName
  67093. */
  67094. public function shouldCodeCoverageBeCollectedFor(string $className, string $methodName): bool
  67095. {
  67096. $metadataForClass = Registry::parser()->forClass($className);
  67097. $metadataForMethod = Registry::parser()->forMethod($className, $methodName);
  67098. if ($metadataForMethod->isCoversNothing()->isNotEmpty()) {
  67099. return \false;
  67100. }
  67101. if ($metadataForMethod->isCovers()->isNotEmpty() || $metadataForMethod->isCoversClass()->isNotEmpty() || $metadataForMethod->isCoversFunction()->isNotEmpty()) {
  67102. return \true;
  67103. }
  67104. if ($metadataForClass->isCoversNothing()->isNotEmpty()) {
  67105. return \false;
  67106. }
  67107. return \true;
  67108. }
  67109. /**
  67110. * @psalm-return list<class-string>
  67111. */
  67112. private function testCaseClassesIn(TestSuite $testSuite): array
  67113. {
  67114. $classNames = [];
  67115. foreach (new RecursiveIteratorIterator($testSuite) as $test) {
  67116. $classNames[] = $test::class;
  67117. }
  67118. return array_values(array_unique($classNames));
  67119. }
  67120. /**
  67121. * @psalm-param class-string $className
  67122. */
  67123. private function codeUnitsIgnoredBy(string $className): CodeUnitCollection
  67124. {
  67125. $codeUnits = CodeUnitCollection::fromList();
  67126. $mapper = new Mapper();
  67127. foreach (Registry::parser()->forClass($className) as $metadata) {
  67128. if ($metadata instanceof IgnoreClassForCodeCoverage) {
  67129. $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className()));
  67130. }
  67131. if ($metadata instanceof IgnoreMethodForCodeCoverage) {
  67132. $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className() . '::' . $metadata->methodName()));
  67133. }
  67134. if ($metadata instanceof IgnoreFunctionForCodeCoverage) {
  67135. $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits('::' . $metadata->functionName()));
  67136. }
  67137. }
  67138. return $codeUnits;
  67139. }
  67140. /**
  67141. * @throws InvalidCoversTargetException
  67142. */
  67143. private function mapToCodeUnits(CoversClass|CoversFunction|UsesClass|UsesFunction $metadata): CodeUnitCollection
  67144. {
  67145. $mapper = new Mapper();
  67146. try {
  67147. return $mapper->stringToCodeUnits($metadata->asStringForCodeUnitMapper());
  67148. } catch (CodeUnitException $e) {
  67149. if ($metadata->isCoversClass() || $metadata->isUsesClass()) {
  67150. if (interface_exists($metadata->className())) {
  67151. $type = 'Interface';
  67152. } else {
  67153. $type = 'Class';
  67154. }
  67155. } else {
  67156. $type = 'Function';
  67157. }
  67158. throw new InvalidCoversTargetException(sprintf('%s "%s" is not a valid target for code coverage', $type, $metadata->asStringForCodeUnitMapper()), $e->getCode(), $e);
  67159. }
  67160. }
  67161. }
  67162. <?php
  67163. declare (strict_types=1);
  67164. /*
  67165. * This file is part of PHPUnit.
  67166. *
  67167. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67168. *
  67169. * For the full copyright and license information, please view the LICENSE
  67170. * file that was distributed with this source code.
  67171. */
  67172. namespace PHPUnit\Metadata\Api;
  67173. use const JSON_ERROR_NONE;
  67174. use const PREG_OFFSET_CAPTURE;
  67175. use function array_key_exists;
  67176. use function assert;
  67177. use function explode;
  67178. use function get_debug_type;
  67179. use function is_array;
  67180. use function is_int;
  67181. use function is_string;
  67182. use function json_decode;
  67183. use function json_last_error;
  67184. use function json_last_error_msg;
  67185. use function preg_match;
  67186. use function preg_replace;
  67187. use function rtrim;
  67188. use function sprintf;
  67189. use function str_replace;
  67190. use function strlen;
  67191. use function substr;
  67192. use function trim;
  67193. use PHPUnit\Event;
  67194. use PHPUnit\Event\Code\TestMethod;
  67195. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  67196. use PHPUnit\Event\TestData\TestDataCollection;
  67197. use PHPUnit\Framework\InvalidDataProviderException;
  67198. use PHPUnit\Metadata\DataProvider as DataProviderMetadata;
  67199. use PHPUnit\Metadata\MetadataCollection;
  67200. use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
  67201. use PHPUnit\Metadata\TestWith;
  67202. use PHPUnit\Util\Reflection;
  67203. use ReflectionClass;
  67204. use ReflectionMethod;
  67205. use Throwable;
  67206. /**
  67207. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67208. *
  67209. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  67210. */
  67211. final class DataProvider
  67212. {
  67213. /**
  67214. * @psalm-param class-string $className
  67215. * @psalm-param non-empty-string $methodName
  67216. *
  67217. * @throws InvalidDataProviderException
  67218. */
  67219. public function providedData(string $className, string $methodName): ?array
  67220. {
  67221. $dataProvider = MetadataRegistry::parser()->forMethod($className, $methodName)->isDataProvider();
  67222. $testWith = MetadataRegistry::parser()->forMethod($className, $methodName)->isTestWith();
  67223. if ($dataProvider->isEmpty() && $testWith->isEmpty()) {
  67224. return $this->dataProvidedByTestWithAnnotation($className, $methodName);
  67225. }
  67226. if ($dataProvider->isNotEmpty()) {
  67227. $data = $this->dataProvidedByMethods($className, $methodName, $dataProvider);
  67228. } else {
  67229. $data = $this->dataProvidedByMetadata($testWith);
  67230. }
  67231. if ($data === []) {
  67232. throw new InvalidDataProviderException('Empty data set provided by data provider');
  67233. }
  67234. foreach ($data as $key => $value) {
  67235. if (!is_array($value)) {
  67236. throw new InvalidDataProviderException(sprintf('Data set %s is invalid', is_int($key) ? '#' . $key : '"' . $key . '"'));
  67237. }
  67238. }
  67239. return $data;
  67240. }
  67241. /**
  67242. * @psalm-param class-string $className
  67243. * @psalm-param non-empty-string $methodName
  67244. *
  67245. * @throws InvalidDataProviderException
  67246. */
  67247. private function dataProvidedByMethods(string $className, string $methodName, MetadataCollection $dataProvider): array
  67248. {
  67249. $testMethod = new Event\Code\ClassMethod($className, $methodName);
  67250. $methodsCalled = [];
  67251. $result = [];
  67252. foreach ($dataProvider as $_dataProvider) {
  67253. assert($_dataProvider instanceof DataProviderMetadata);
  67254. $dataProviderMethod = new Event\Code\ClassMethod($_dataProvider->className(), $_dataProvider->methodName());
  67255. Event\Facade::emitter()->dataProviderMethodCalled($testMethod, $dataProviderMethod);
  67256. $methodsCalled[] = $dataProviderMethod;
  67257. try {
  67258. $class = new ReflectionClass($_dataProvider->className());
  67259. $method = $class->getMethod($_dataProvider->methodName());
  67260. $object = null;
  67261. if (!$method->isPublic()) {
  67262. Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() is not public', $_dataProvider->className(), $_dataProvider->methodName()));
  67263. }
  67264. if (!$method->isStatic()) {
  67265. Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() is not static', $_dataProvider->className(), $_dataProvider->methodName()));
  67266. $object = $class->newInstanceWithoutConstructor();
  67267. }
  67268. if ($method->getNumberOfParameters() === 0) {
  67269. $data = $method->invoke($object);
  67270. } else {
  67271. Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() expects an argument', $_dataProvider->className(), $_dataProvider->methodName()));
  67272. $data = $method->invoke($object, $_dataProvider->methodName());
  67273. }
  67274. } catch (Throwable $e) {
  67275. Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
  67276. throw new InvalidDataProviderException($e->getMessage(), $e->getCode(), $e);
  67277. }
  67278. foreach ($data as $key => $value) {
  67279. if (is_int($key)) {
  67280. $result[] = $value;
  67281. } elseif (is_string($key)) {
  67282. if (array_key_exists($key, $result)) {
  67283. Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
  67284. throw new InvalidDataProviderException(sprintf('The key "%s" has already been defined by a previous data provider', $key));
  67285. }
  67286. $result[$key] = $value;
  67287. } else {
  67288. throw new InvalidDataProviderException(sprintf('The key must be an integer or a string, %s given', get_debug_type($key)));
  67289. }
  67290. }
  67291. }
  67292. Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
  67293. return $result;
  67294. }
  67295. private function dataProvidedByMetadata(MetadataCollection $testWith): array
  67296. {
  67297. $result = [];
  67298. foreach ($testWith as $_testWith) {
  67299. assert($_testWith instanceof TestWith);
  67300. $result[] = $_testWith->data();
  67301. }
  67302. return $result;
  67303. }
  67304. /**
  67305. * @psalm-param class-string $className
  67306. *
  67307. * @throws InvalidDataProviderException
  67308. */
  67309. private function dataProvidedByTestWithAnnotation(string $className, string $methodName): ?array
  67310. {
  67311. $docComment = (new ReflectionMethod($className, $methodName))->getDocComment();
  67312. if ($docComment === \false) {
  67313. return null;
  67314. }
  67315. $docComment = str_replace("\r\n", "\n", $docComment);
  67316. $docComment = preg_replace('/\n\s*\*\s?/', "\n", $docComment);
  67317. $docComment = substr($docComment, 0, -1);
  67318. $docComment = rtrim($docComment, "\n");
  67319. if (!preg_match('/@testWith\s+/', $docComment, $matches, PREG_OFFSET_CAPTURE)) {
  67320. return null;
  67321. }
  67322. $offset = strlen($matches[0][0]) + (int) $matches[0][1];
  67323. $annotationContent = substr($docComment, $offset);
  67324. $data = [];
  67325. foreach (explode("\n", $annotationContent) as $candidateRow) {
  67326. $candidateRow = trim($candidateRow);
  67327. if ($candidateRow === '' || $candidateRow[0] !== '[') {
  67328. break;
  67329. }
  67330. $dataSet = json_decode($candidateRow, \true);
  67331. if (json_last_error() !== JSON_ERROR_NONE) {
  67332. throw new InvalidDataProviderException('The data set for the @testWith annotation cannot be parsed: ' . json_last_error_msg());
  67333. }
  67334. $data[] = $dataSet;
  67335. }
  67336. if (!$data) {
  67337. throw new InvalidDataProviderException('The data set for the @testWith annotation cannot be parsed.');
  67338. }
  67339. return $data;
  67340. }
  67341. /**
  67342. * @psalm-param class-string $className
  67343. * @psalm-param non-empty-string $methodName
  67344. *
  67345. * @throws MoreThanOneDataSetFromDataProviderException
  67346. */
  67347. private function valueObjectForTestMethodWithoutTestData(string $className, string $methodName): TestMethod
  67348. {
  67349. $location = Reflection::sourceLocationFor($className, $methodName);
  67350. return new TestMethod($className, $methodName, $location['file'], $location['line'], Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataRegistry::parser()->forClassAndMethod($className, $methodName), TestDataCollection::fromArray([]));
  67351. }
  67352. }
  67353. <?php
  67354. declare (strict_types=1);
  67355. /*
  67356. * This file is part of PHPUnit.
  67357. *
  67358. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67359. *
  67360. * For the full copyright and license information, please view the LICENSE
  67361. * file that was distributed with this source code.
  67362. */
  67363. namespace PHPUnit\Metadata\Api;
  67364. use function assert;
  67365. use PHPUnit\Framework\ExecutionOrderDependency;
  67366. use PHPUnit\Metadata\DependsOnClass;
  67367. use PHPUnit\Metadata\DependsOnMethod;
  67368. use PHPUnit\Metadata\Parser\Registry;
  67369. /**
  67370. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67371. *
  67372. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  67373. */
  67374. final class Dependencies
  67375. {
  67376. /**
  67377. * @psalm-param class-string $className
  67378. * @psalm-param non-empty-string $methodName
  67379. *
  67380. * @psalm-return list<ExecutionOrderDependency>
  67381. */
  67382. public static function dependencies(string $className, string $methodName): array
  67383. {
  67384. $dependencies = [];
  67385. foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isDepends() as $metadata) {
  67386. if ($metadata->isDependsOnClass()) {
  67387. assert($metadata instanceof DependsOnClass);
  67388. $dependencies[] = ExecutionOrderDependency::forClass($metadata);
  67389. continue;
  67390. }
  67391. assert($metadata instanceof DependsOnMethod);
  67392. if (empty($metadata->methodName())) {
  67393. $dependencies[] = ExecutionOrderDependency::invalid();
  67394. continue;
  67395. }
  67396. $dependencies[] = ExecutionOrderDependency::forMethod($metadata);
  67397. }
  67398. return $dependencies;
  67399. }
  67400. }
  67401. <?php
  67402. declare (strict_types=1);
  67403. /*
  67404. * This file is part of PHPUnit.
  67405. *
  67406. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67407. *
  67408. * For the full copyright and license information, please view the LICENSE
  67409. * file that was distributed with this source code.
  67410. */
  67411. namespace PHPUnit\Metadata\Api;
  67412. use function array_flip;
  67413. use function array_key_exists;
  67414. use function array_unique;
  67415. use function assert;
  67416. use function strtolower;
  67417. use function trim;
  67418. use PHPUnit\Framework\TestSize\TestSize;
  67419. use PHPUnit\Metadata\Covers;
  67420. use PHPUnit\Metadata\CoversClass;
  67421. use PHPUnit\Metadata\CoversFunction;
  67422. use PHPUnit\Metadata\Group;
  67423. use PHPUnit\Metadata\Parser\Registry;
  67424. use PHPUnit\Metadata\Uses;
  67425. use PHPUnit\Metadata\UsesClass;
  67426. use PHPUnit\Metadata\UsesFunction;
  67427. /**
  67428. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67429. *
  67430. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  67431. */
  67432. final class Groups
  67433. {
  67434. /**
  67435. * @var array<string, array<int, string>>
  67436. */
  67437. private static array $groupCache = [];
  67438. /**
  67439. * @psalm-param class-string $className
  67440. * @psalm-param non-empty-string $methodName
  67441. *
  67442. * @psalm-return array<int, string>
  67443. */
  67444. public function groups(string $className, string $methodName, bool $includeVirtual = \true): array
  67445. {
  67446. $key = $className . '::' . $methodName . '::' . $includeVirtual;
  67447. if (array_key_exists($key, self::$groupCache)) {
  67448. return self::$groupCache[$key];
  67449. }
  67450. $groups = [];
  67451. foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isGroup() as $group) {
  67452. assert($group instanceof Group);
  67453. $groups[] = $group->groupName();
  67454. }
  67455. if ($groups === []) {
  67456. $groups[] = 'default';
  67457. }
  67458. if (!$includeVirtual) {
  67459. return self::$groupCache[$key] = array_unique($groups);
  67460. }
  67461. foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
  67462. if ($metadata->isCoversClass() || $metadata->isCoversFunction()) {
  67463. assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction);
  67464. $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper());
  67465. continue;
  67466. }
  67467. if ($metadata->isCovers()) {
  67468. assert($metadata instanceof Covers);
  67469. $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->target());
  67470. continue;
  67471. }
  67472. if ($metadata->isUsesClass() || $metadata->isUsesFunction()) {
  67473. assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction);
  67474. $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper());
  67475. continue;
  67476. }
  67477. if ($metadata->isUses()) {
  67478. assert($metadata instanceof Uses);
  67479. $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->target());
  67480. }
  67481. }
  67482. return self::$groupCache[$key] = array_unique($groups);
  67483. }
  67484. /**
  67485. * @psalm-param class-string $className
  67486. * @psalm-param non-empty-string $methodName
  67487. */
  67488. public function size(string $className, string $methodName): TestSize
  67489. {
  67490. $groups = array_flip($this->groups($className, $methodName));
  67491. if (isset($groups['large'])) {
  67492. return TestSize::large();
  67493. }
  67494. if (isset($groups['medium'])) {
  67495. return TestSize::medium();
  67496. }
  67497. if (isset($groups['small'])) {
  67498. return TestSize::small();
  67499. }
  67500. return TestSize::unknown();
  67501. }
  67502. private function canonicalizeName(string $name): string
  67503. {
  67504. return strtolower(trim($name, '\\'));
  67505. }
  67506. }
  67507. <?php
  67508. declare (strict_types=1);
  67509. /*
  67510. * This file is part of PHPUnit.
  67511. *
  67512. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67513. *
  67514. * For the full copyright and license information, please view the LICENSE
  67515. * file that was distributed with this source code.
  67516. */
  67517. namespace PHPUnit\Metadata\Api;
  67518. use function array_unshift;
  67519. use function assert;
  67520. use function class_exists;
  67521. use PHPUnit\Metadata\Parser\Registry;
  67522. use PHPUnit\Util\Reflection;
  67523. use ReflectionClass;
  67524. /**
  67525. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67526. *
  67527. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  67528. */
  67529. final class HookMethods
  67530. {
  67531. /**
  67532. * @psalm-var array<class-string, array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}>
  67533. */
  67534. private static array $hookMethods = [];
  67535. /**
  67536. * @psalm-param class-string $className
  67537. *
  67538. * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}
  67539. */
  67540. public function hookMethods(string $className): array
  67541. {
  67542. if (!class_exists($className)) {
  67543. return self::emptyHookMethodsArray();
  67544. }
  67545. if (isset(self::$hookMethods[$className])) {
  67546. return self::$hookMethods[$className];
  67547. }
  67548. self::$hookMethods[$className] = self::emptyHookMethodsArray();
  67549. foreach (Reflection::methodsInTestClass(new ReflectionClass($className)) as $method) {
  67550. $methodName = $method->getName();
  67551. assert(!empty($methodName));
  67552. $metadata = Registry::parser()->forMethod($className, $methodName);
  67553. if ($method->isStatic()) {
  67554. if ($metadata->isBeforeClass()->isNotEmpty()) {
  67555. array_unshift(self::$hookMethods[$className]['beforeClass'], $methodName);
  67556. }
  67557. if ($metadata->isAfterClass()->isNotEmpty()) {
  67558. self::$hookMethods[$className]['afterClass'][] = $methodName;
  67559. }
  67560. }
  67561. if ($metadata->isBefore()->isNotEmpty()) {
  67562. array_unshift(self::$hookMethods[$className]['before'], $methodName);
  67563. }
  67564. if ($metadata->isPreCondition()->isNotEmpty()) {
  67565. array_unshift(self::$hookMethods[$className]['preCondition'], $methodName);
  67566. }
  67567. if ($metadata->isPostCondition()->isNotEmpty()) {
  67568. self::$hookMethods[$className]['postCondition'][] = $methodName;
  67569. }
  67570. if ($metadata->isAfter()->isNotEmpty()) {
  67571. self::$hookMethods[$className]['after'][] = $methodName;
  67572. }
  67573. }
  67574. return self::$hookMethods[$className];
  67575. }
  67576. /**
  67577. * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}
  67578. */
  67579. private function emptyHookMethodsArray(): array
  67580. {
  67581. return ['beforeClass' => ['setUpBeforeClass'], 'before' => ['setUp'], 'preCondition' => ['assertPreConditions'], 'postCondition' => ['assertPostConditions'], 'after' => ['tearDown'], 'afterClass' => ['tearDownAfterClass']];
  67582. }
  67583. }
  67584. <?php
  67585. declare (strict_types=1);
  67586. /*
  67587. * This file is part of PHPUnit.
  67588. *
  67589. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67590. *
  67591. * For the full copyright and license information, please view the LICENSE
  67592. * file that was distributed with this source code.
  67593. */
  67594. namespace PHPUnit\Metadata\Api;
  67595. use const PHP_OS;
  67596. use const PHP_OS_FAMILY;
  67597. use const PHP_VERSION;
  67598. use function addcslashes;
  67599. use function assert;
  67600. use function extension_loaded;
  67601. use function function_exists;
  67602. use function ini_get;
  67603. use function method_exists;
  67604. use function phpversion;
  67605. use function preg_match;
  67606. use function sprintf;
  67607. use PHPUnit\Metadata\Parser\Registry;
  67608. use PHPUnit\Metadata\RequiresFunction;
  67609. use PHPUnit\Metadata\RequiresMethod;
  67610. use PHPUnit\Metadata\RequiresOperatingSystem;
  67611. use PHPUnit\Metadata\RequiresOperatingSystemFamily;
  67612. use PHPUnit\Metadata\RequiresPhp;
  67613. use PHPUnit\Metadata\RequiresPhpExtension;
  67614. use PHPUnit\Metadata\RequiresPhpunit;
  67615. use PHPUnit\Metadata\RequiresSetting;
  67616. use PHPUnit\Runner\Version;
  67617. /**
  67618. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67619. *
  67620. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  67621. */
  67622. final class Requirements
  67623. {
  67624. /**
  67625. * @psalm-param class-string $className
  67626. * @psalm-param non-empty-string $methodName
  67627. *
  67628. * @psalm-return list<string>
  67629. */
  67630. public function requirementsNotSatisfiedFor(string $className, string $methodName): array
  67631. {
  67632. $notSatisfied = [];
  67633. foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
  67634. if ($metadata->isRequiresPhp()) {
  67635. assert($metadata instanceof RequiresPhp);
  67636. if (!$metadata->versionRequirement()->isSatisfiedBy(PHP_VERSION)) {
  67637. $notSatisfied[] = sprintf('PHP %s is required.', $metadata->versionRequirement()->asString());
  67638. }
  67639. }
  67640. if ($metadata->isRequiresPhpExtension()) {
  67641. assert($metadata instanceof RequiresPhpExtension);
  67642. if (!extension_loaded($metadata->extension()) || $metadata->hasVersionRequirement() && !$metadata->versionRequirement()->isSatisfiedBy(phpversion($metadata->extension()))) {
  67643. $notSatisfied[] = sprintf('PHP extension %s%s is required.', $metadata->extension(), $metadata->hasVersionRequirement() ? ' ' . $metadata->versionRequirement()->asString() : '');
  67644. }
  67645. }
  67646. if ($metadata->isRequiresPhpunit()) {
  67647. assert($metadata instanceof RequiresPhpunit);
  67648. if (!$metadata->versionRequirement()->isSatisfiedBy(Version::id())) {
  67649. $notSatisfied[] = sprintf('PHPUnit %s is required.', $metadata->versionRequirement()->asString());
  67650. }
  67651. }
  67652. if ($metadata->isRequiresOperatingSystemFamily()) {
  67653. assert($metadata instanceof RequiresOperatingSystemFamily);
  67654. if ($metadata->operatingSystemFamily() !== PHP_OS_FAMILY) {
  67655. $notSatisfied[] = sprintf('Operating system %s is required.', $metadata->operatingSystemFamily());
  67656. }
  67657. }
  67658. if ($metadata->isRequiresOperatingSystem()) {
  67659. assert($metadata instanceof RequiresOperatingSystem);
  67660. $pattern = sprintf('/%s/i', addcslashes($metadata->operatingSystem(), '/'));
  67661. if (!preg_match($pattern, PHP_OS)) {
  67662. $notSatisfied[] = sprintf('Operating system %s is required.', $metadata->operatingSystem());
  67663. }
  67664. }
  67665. if ($metadata->isRequiresFunction()) {
  67666. assert($metadata instanceof RequiresFunction);
  67667. if (!function_exists($metadata->functionName())) {
  67668. $notSatisfied[] = sprintf('Function %s() is required.', $metadata->functionName());
  67669. }
  67670. }
  67671. if ($metadata->isRequiresMethod()) {
  67672. assert($metadata instanceof RequiresMethod);
  67673. if (!method_exists($metadata->className(), $metadata->methodName())) {
  67674. $notSatisfied[] = sprintf('Method %s::%s() is required.', $metadata->className(), $metadata->methodName());
  67675. }
  67676. }
  67677. if ($metadata->isRequiresSetting()) {
  67678. assert($metadata instanceof RequiresSetting);
  67679. if (ini_get($metadata->setting()) !== $metadata->value()) {
  67680. $notSatisfied[] = sprintf('Setting "%s" is required to be "%s".', $metadata->setting(), $metadata->value());
  67681. }
  67682. }
  67683. }
  67684. return $notSatisfied;
  67685. }
  67686. }
  67687. <?php
  67688. declare (strict_types=1);
  67689. /*
  67690. * This file is part of PHPUnit.
  67691. *
  67692. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67693. *
  67694. * For the full copyright and license information, please view the LICENSE
  67695. * file that was distributed with this source code.
  67696. */
  67697. namespace PHPUnit\Metadata;
  67698. /**
  67699. * @psalm-immutable
  67700. *
  67701. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67702. */
  67703. final class BackupGlobals extends \PHPUnit\Metadata\Metadata
  67704. {
  67705. private readonly bool $enabled;
  67706. /**
  67707. * @psalm-param 0|1 $level
  67708. */
  67709. protected function __construct(int $level, bool $enabled)
  67710. {
  67711. parent::__construct($level);
  67712. $this->enabled = $enabled;
  67713. }
  67714. /**
  67715. * @psalm-assert-if-true BackupGlobals $this
  67716. */
  67717. public function isBackupGlobals(): bool
  67718. {
  67719. return \true;
  67720. }
  67721. public function enabled(): bool
  67722. {
  67723. return $this->enabled;
  67724. }
  67725. }
  67726. <?php
  67727. declare (strict_types=1);
  67728. /*
  67729. * This file is part of PHPUnit.
  67730. *
  67731. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67732. *
  67733. * For the full copyright and license information, please view the LICENSE
  67734. * file that was distributed with this source code.
  67735. */
  67736. namespace PHPUnit\Metadata;
  67737. /**
  67738. * @psalm-immutable
  67739. *
  67740. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67741. */
  67742. final class BackupStaticProperties extends \PHPUnit\Metadata\Metadata
  67743. {
  67744. private readonly bool $enabled;
  67745. /**
  67746. * @psalm-param 0|1 $level
  67747. */
  67748. protected function __construct(int $level, bool $enabled)
  67749. {
  67750. parent::__construct($level);
  67751. $this->enabled = $enabled;
  67752. }
  67753. /**
  67754. * @psalm-assert-if-true BackupStaticProperties $this
  67755. */
  67756. public function isBackupStaticProperties(): bool
  67757. {
  67758. return \true;
  67759. }
  67760. public function enabled(): bool
  67761. {
  67762. return $this->enabled;
  67763. }
  67764. }
  67765. <?php
  67766. declare (strict_types=1);
  67767. /*
  67768. * This file is part of PHPUnit.
  67769. *
  67770. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67771. *
  67772. * For the full copyright and license information, please view the LICENSE
  67773. * file that was distributed with this source code.
  67774. */
  67775. namespace PHPUnit\Metadata;
  67776. /**
  67777. * @psalm-immutable
  67778. *
  67779. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67780. */
  67781. final class Before extends \PHPUnit\Metadata\Metadata
  67782. {
  67783. /**
  67784. * @psalm-assert-if-true Before $this
  67785. */
  67786. public function isBefore(): bool
  67787. {
  67788. return \true;
  67789. }
  67790. }
  67791. <?php
  67792. declare (strict_types=1);
  67793. /*
  67794. * This file is part of PHPUnit.
  67795. *
  67796. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67797. *
  67798. * For the full copyright and license information, please view the LICENSE
  67799. * file that was distributed with this source code.
  67800. */
  67801. namespace PHPUnit\Metadata;
  67802. /**
  67803. * @psalm-immutable
  67804. *
  67805. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67806. */
  67807. final class BeforeClass extends \PHPUnit\Metadata\Metadata
  67808. {
  67809. /**
  67810. * @psalm-assert-if-true BeforeClass $this
  67811. */
  67812. public function isBeforeClass(): bool
  67813. {
  67814. return \true;
  67815. }
  67816. }
  67817. <?php
  67818. declare (strict_types=1);
  67819. /*
  67820. * This file is part of PHPUnit.
  67821. *
  67822. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67823. *
  67824. * For the full copyright and license information, please view the LICENSE
  67825. * file that was distributed with this source code.
  67826. */
  67827. namespace PHPUnit\Metadata;
  67828. /**
  67829. * @psalm-immutable
  67830. *
  67831. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67832. */
  67833. final class Covers extends \PHPUnit\Metadata\Metadata
  67834. {
  67835. /**
  67836. * @psalm-var non-empty-string
  67837. */
  67838. private readonly string $target;
  67839. /**
  67840. * @psalm-param 0|1 $level
  67841. * @psalm-param non-empty-string $target
  67842. */
  67843. protected function __construct(int $level, string $target)
  67844. {
  67845. parent::__construct($level);
  67846. $this->target = $target;
  67847. }
  67848. /**
  67849. * @psalm-assert-if-true Covers $this
  67850. */
  67851. public function isCovers(): bool
  67852. {
  67853. return \true;
  67854. }
  67855. /**
  67856. * @psalm-return non-empty-string
  67857. */
  67858. public function target(): string
  67859. {
  67860. return $this->target;
  67861. }
  67862. }
  67863. <?php
  67864. declare (strict_types=1);
  67865. /*
  67866. * This file is part of PHPUnit.
  67867. *
  67868. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67869. *
  67870. * For the full copyright and license information, please view the LICENSE
  67871. * file that was distributed with this source code.
  67872. */
  67873. namespace PHPUnit\Metadata;
  67874. /**
  67875. * @psalm-immutable
  67876. *
  67877. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67878. */
  67879. final class CoversClass extends \PHPUnit\Metadata\Metadata
  67880. {
  67881. /**
  67882. * @psalm-var class-string
  67883. */
  67884. private readonly string $className;
  67885. /**
  67886. * @psalm-param 0|1 $level
  67887. * @psalm-param class-string $className
  67888. */
  67889. protected function __construct(int $level, string $className)
  67890. {
  67891. parent::__construct($level);
  67892. $this->className = $className;
  67893. }
  67894. /**
  67895. * @psalm-assert-if-true CoversClass $this
  67896. */
  67897. public function isCoversClass(): bool
  67898. {
  67899. return \true;
  67900. }
  67901. /**
  67902. * @psalm-return class-string
  67903. */
  67904. public function className(): string
  67905. {
  67906. return $this->className;
  67907. }
  67908. /**
  67909. * @psalm-return class-string
  67910. *
  67911. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  67912. */
  67913. public function asStringForCodeUnitMapper(): string
  67914. {
  67915. return $this->className;
  67916. }
  67917. }
  67918. <?php
  67919. declare (strict_types=1);
  67920. /*
  67921. * This file is part of PHPUnit.
  67922. *
  67923. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67924. *
  67925. * For the full copyright and license information, please view the LICENSE
  67926. * file that was distributed with this source code.
  67927. */
  67928. namespace PHPUnit\Metadata;
  67929. /**
  67930. * @psalm-immutable
  67931. *
  67932. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67933. */
  67934. final class CoversDefaultClass extends \PHPUnit\Metadata\Metadata
  67935. {
  67936. /**
  67937. * @psalm-var class-string
  67938. */
  67939. private readonly string $className;
  67940. /**
  67941. * @psalm-param 0|1 $level
  67942. * @psalm-param class-string $className
  67943. */
  67944. protected function __construct(int $level, string $className)
  67945. {
  67946. parent::__construct($level);
  67947. $this->className = $className;
  67948. }
  67949. /**
  67950. * @psalm-assert-if-true CoversDefaultClass $this
  67951. */
  67952. public function isCoversDefaultClass(): bool
  67953. {
  67954. return \true;
  67955. }
  67956. /**
  67957. * @psalm-return class-string
  67958. */
  67959. public function className(): string
  67960. {
  67961. return $this->className;
  67962. }
  67963. }
  67964. <?php
  67965. declare (strict_types=1);
  67966. /*
  67967. * This file is part of PHPUnit.
  67968. *
  67969. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  67970. *
  67971. * For the full copyright and license information, please view the LICENSE
  67972. * file that was distributed with this source code.
  67973. */
  67974. namespace PHPUnit\Metadata;
  67975. /**
  67976. * @psalm-immutable
  67977. *
  67978. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  67979. */
  67980. final class CoversFunction extends \PHPUnit\Metadata\Metadata
  67981. {
  67982. /**
  67983. * @psalm-var non-empty-string
  67984. */
  67985. private readonly string $functionName;
  67986. /**
  67987. * @psalm-param 0|1 $level
  67988. * @psalm-param non-empty-string $functionName
  67989. */
  67990. protected function __construct(int $level, string $functionName)
  67991. {
  67992. parent::__construct($level);
  67993. $this->functionName = $functionName;
  67994. }
  67995. /**
  67996. * @psalm-assert-if-true CoversFunction $this
  67997. */
  67998. public function isCoversFunction(): bool
  67999. {
  68000. return \true;
  68001. }
  68002. /**
  68003. * @psalm-return non-empty-string
  68004. */
  68005. public function functionName(): string
  68006. {
  68007. return $this->functionName;
  68008. }
  68009. /**
  68010. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  68011. */
  68012. public function asStringForCodeUnitMapper(): string
  68013. {
  68014. return '::' . $this->functionName;
  68015. }
  68016. }
  68017. <?php
  68018. declare (strict_types=1);
  68019. /*
  68020. * This file is part of PHPUnit.
  68021. *
  68022. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68023. *
  68024. * For the full copyright and license information, please view the LICENSE
  68025. * file that was distributed with this source code.
  68026. */
  68027. namespace PHPUnit\Metadata;
  68028. /**
  68029. * @psalm-immutable
  68030. *
  68031. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68032. */
  68033. final class CoversNothing extends \PHPUnit\Metadata\Metadata
  68034. {
  68035. /**
  68036. * @psalm-assert-if-true CoversNothing $this
  68037. */
  68038. public function isCoversNothing(): bool
  68039. {
  68040. return \true;
  68041. }
  68042. }
  68043. <?php
  68044. declare (strict_types=1);
  68045. /*
  68046. * This file is part of PHPUnit.
  68047. *
  68048. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68049. *
  68050. * For the full copyright and license information, please view the LICENSE
  68051. * file that was distributed with this source code.
  68052. */
  68053. namespace PHPUnit\Metadata;
  68054. /**
  68055. * @psalm-immutable
  68056. *
  68057. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68058. */
  68059. final class DataProvider extends \PHPUnit\Metadata\Metadata
  68060. {
  68061. /**
  68062. * @psalm-var class-string
  68063. */
  68064. private readonly string $className;
  68065. /**
  68066. * @psalm-var non-empty-string
  68067. */
  68068. private readonly string $methodName;
  68069. /**
  68070. * @psalm-param 0|1 $level
  68071. * @psalm-param class-string $className
  68072. * @psalm-param non-empty-string $methodName
  68073. */
  68074. protected function __construct(int $level, string $className, string $methodName)
  68075. {
  68076. parent::__construct($level);
  68077. $this->className = $className;
  68078. $this->methodName = $methodName;
  68079. }
  68080. /**
  68081. * @psalm-assert-if-true DataProvider $this
  68082. */
  68083. public function isDataProvider(): bool
  68084. {
  68085. return \true;
  68086. }
  68087. /**
  68088. * @psalm-return class-string
  68089. */
  68090. public function className(): string
  68091. {
  68092. return $this->className;
  68093. }
  68094. /**
  68095. * @psalm-return non-empty-string
  68096. */
  68097. public function methodName(): string
  68098. {
  68099. return $this->methodName;
  68100. }
  68101. }
  68102. <?php
  68103. declare (strict_types=1);
  68104. /*
  68105. * This file is part of PHPUnit.
  68106. *
  68107. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68108. *
  68109. * For the full copyright and license information, please view the LICENSE
  68110. * file that was distributed with this source code.
  68111. */
  68112. namespace PHPUnit\Metadata;
  68113. /**
  68114. * @psalm-immutable
  68115. *
  68116. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68117. */
  68118. final class DependsOnClass extends \PHPUnit\Metadata\Metadata
  68119. {
  68120. /**
  68121. * @psalm-var class-string
  68122. */
  68123. private readonly string $className;
  68124. private readonly bool $deepClone;
  68125. private readonly bool $shallowClone;
  68126. /**
  68127. * @psalm-param 0|1 $level
  68128. * @psalm-param class-string $className
  68129. */
  68130. protected function __construct(int $level, string $className, bool $deepClone, bool $shallowClone)
  68131. {
  68132. parent::__construct($level);
  68133. $this->className = $className;
  68134. $this->deepClone = $deepClone;
  68135. $this->shallowClone = $shallowClone;
  68136. }
  68137. /**
  68138. * @psalm-assert-if-true DependsOnClass $this
  68139. */
  68140. public function isDependsOnClass(): bool
  68141. {
  68142. return \true;
  68143. }
  68144. /**
  68145. * @psalm-return class-string
  68146. */
  68147. public function className(): string
  68148. {
  68149. return $this->className;
  68150. }
  68151. public function deepClone(): bool
  68152. {
  68153. return $this->deepClone;
  68154. }
  68155. public function shallowClone(): bool
  68156. {
  68157. return $this->shallowClone;
  68158. }
  68159. }
  68160. <?php
  68161. declare (strict_types=1);
  68162. /*
  68163. * This file is part of PHPUnit.
  68164. *
  68165. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68166. *
  68167. * For the full copyright and license information, please view the LICENSE
  68168. * file that was distributed with this source code.
  68169. */
  68170. namespace PHPUnit\Metadata;
  68171. /**
  68172. * @psalm-immutable
  68173. *
  68174. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68175. */
  68176. final class DependsOnMethod extends \PHPUnit\Metadata\Metadata
  68177. {
  68178. /**
  68179. * @psalm-var class-string
  68180. */
  68181. private readonly string $className;
  68182. /**
  68183. * @psalm-var non-empty-string
  68184. */
  68185. private readonly string $methodName;
  68186. private readonly bool $deepClone;
  68187. private readonly bool $shallowClone;
  68188. /**
  68189. * @psalm-param 0|1 $level
  68190. * @psalm-param class-string $className
  68191. * @psalm-param non-empty-string $methodName
  68192. */
  68193. protected function __construct(int $level, string $className, string $methodName, bool $deepClone, bool $shallowClone)
  68194. {
  68195. parent::__construct($level);
  68196. $this->className = $className;
  68197. $this->methodName = $methodName;
  68198. $this->deepClone = $deepClone;
  68199. $this->shallowClone = $shallowClone;
  68200. }
  68201. /**
  68202. * @psalm-assert-if-true DependsOnMethod $this
  68203. */
  68204. public function isDependsOnMethod(): bool
  68205. {
  68206. return \true;
  68207. }
  68208. /**
  68209. * @psalm-return class-string
  68210. */
  68211. public function className(): string
  68212. {
  68213. return $this->className;
  68214. }
  68215. /**
  68216. * @psalm-return non-empty-string
  68217. */
  68218. public function methodName(): string
  68219. {
  68220. return $this->methodName;
  68221. }
  68222. public function deepClone(): bool
  68223. {
  68224. return $this->deepClone;
  68225. }
  68226. public function shallowClone(): bool
  68227. {
  68228. return $this->shallowClone;
  68229. }
  68230. }
  68231. <?php
  68232. declare (strict_types=1);
  68233. /*
  68234. * This file is part of PHPUnit.
  68235. *
  68236. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68237. *
  68238. * For the full copyright and license information, please view the LICENSE
  68239. * file that was distributed with this source code.
  68240. */
  68241. namespace PHPUnit\Metadata;
  68242. /**
  68243. * @psalm-immutable
  68244. *
  68245. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68246. */
  68247. final class DoesNotPerformAssertions extends \PHPUnit\Metadata\Metadata
  68248. {
  68249. /**
  68250. * @psalm-assert-if-true DoesNotPerformAssertions $this
  68251. */
  68252. public function isDoesNotPerformAssertions(): bool
  68253. {
  68254. return \true;
  68255. }
  68256. }
  68257. <?php
  68258. declare (strict_types=1);
  68259. /*
  68260. * This file is part of PHPUnit.
  68261. *
  68262. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68263. *
  68264. * For the full copyright and license information, please view the LICENSE
  68265. * file that was distributed with this source code.
  68266. */
  68267. namespace PHPUnit\Metadata;
  68268. use function sprintf;
  68269. use PHPUnit\Exception;
  68270. use RuntimeException;
  68271. /**
  68272. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68273. *
  68274. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  68275. */
  68276. final class AnnotationsAreNotSupportedForInternalClassesException extends RuntimeException implements Exception
  68277. {
  68278. /**
  68279. * @psalm-param class-string $className
  68280. */
  68281. public function __construct(string $className)
  68282. {
  68283. parent::__construct(sprintf('Annotations can only be parsed for user-defined classes, trying to parse annotations for class "%s"', $className));
  68284. }
  68285. }
  68286. <?php
  68287. declare (strict_types=1);
  68288. /*
  68289. * This file is part of PHPUnit.
  68290. *
  68291. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68292. *
  68293. * For the full copyright and license information, please view the LICENSE
  68294. * file that was distributed with this source code.
  68295. */
  68296. namespace PHPUnit\Metadata;
  68297. interface Exception extends \PHPUnit\Exception
  68298. {
  68299. }
  68300. <?php
  68301. declare (strict_types=1);
  68302. /*
  68303. * This file is part of PHPUnit.
  68304. *
  68305. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68306. *
  68307. * For the full copyright and license information, please view the LICENSE
  68308. * file that was distributed with this source code.
  68309. */
  68310. namespace PHPUnit\Metadata;
  68311. use RuntimeException;
  68312. final class InvalidVersionRequirementException extends RuntimeException implements \PHPUnit\Metadata\Exception
  68313. {
  68314. }
  68315. <?php
  68316. declare (strict_types=1);
  68317. /*
  68318. * This file is part of PHPUnit.
  68319. *
  68320. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68321. *
  68322. * For the full copyright and license information, please view the LICENSE
  68323. * file that was distributed with this source code.
  68324. */
  68325. namespace PHPUnit\Metadata;
  68326. use RuntimeException;
  68327. final class NoVersionRequirementException extends RuntimeException implements \PHPUnit\Metadata\Exception
  68328. {
  68329. }
  68330. <?php
  68331. declare (strict_types=1);
  68332. /*
  68333. * This file is part of PHPUnit.
  68334. *
  68335. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68336. *
  68337. * For the full copyright and license information, please view the LICENSE
  68338. * file that was distributed with this source code.
  68339. */
  68340. namespace PHPUnit\Metadata;
  68341. use PHPUnit\Exception;
  68342. use RuntimeException;
  68343. /**
  68344. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68345. *
  68346. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  68347. */
  68348. final class ReflectionException extends RuntimeException implements Exception
  68349. {
  68350. }
  68351. <?php
  68352. declare (strict_types=1);
  68353. /*
  68354. * This file is part of PHPUnit.
  68355. *
  68356. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68357. *
  68358. * For the full copyright and license information, please view the LICENSE
  68359. * file that was distributed with this source code.
  68360. */
  68361. namespace PHPUnit\Metadata;
  68362. /**
  68363. * @psalm-immutable
  68364. *
  68365. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68366. */
  68367. final class ExcludeGlobalVariableFromBackup extends \PHPUnit\Metadata\Metadata
  68368. {
  68369. /**
  68370. * @psalm-var non-empty-string
  68371. */
  68372. private readonly string $globalVariableName;
  68373. /**
  68374. * @psalm-param 0|1 $level
  68375. * @psalm-param non-empty-string $globalVariableName
  68376. */
  68377. protected function __construct(int $level, string $globalVariableName)
  68378. {
  68379. parent::__construct($level);
  68380. $this->globalVariableName = $globalVariableName;
  68381. }
  68382. /**
  68383. * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this
  68384. */
  68385. public function isExcludeGlobalVariableFromBackup(): bool
  68386. {
  68387. return \true;
  68388. }
  68389. /**
  68390. * @psalm-return non-empty-string
  68391. */
  68392. public function globalVariableName(): string
  68393. {
  68394. return $this->globalVariableName;
  68395. }
  68396. }
  68397. <?php
  68398. declare (strict_types=1);
  68399. /*
  68400. * This file is part of PHPUnit.
  68401. *
  68402. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68403. *
  68404. * For the full copyright and license information, please view the LICENSE
  68405. * file that was distributed with this source code.
  68406. */
  68407. namespace PHPUnit\Metadata;
  68408. /**
  68409. * @psalm-immutable
  68410. *
  68411. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68412. */
  68413. final class ExcludeStaticPropertyFromBackup extends \PHPUnit\Metadata\Metadata
  68414. {
  68415. /**
  68416. * @psalm-var class-string
  68417. */
  68418. private readonly string $className;
  68419. /**
  68420. * @psalm-var non-empty-string
  68421. */
  68422. private readonly string $propertyName;
  68423. /**
  68424. * @psalm-param 0|1 $level
  68425. * @psalm-param class-string $className
  68426. * @psalm-param non-empty-string $propertyName
  68427. */
  68428. protected function __construct(int $level, string $className, string $propertyName)
  68429. {
  68430. parent::__construct($level);
  68431. $this->className = $className;
  68432. $this->propertyName = $propertyName;
  68433. }
  68434. /**
  68435. * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this
  68436. */
  68437. public function isExcludeStaticPropertyFromBackup(): bool
  68438. {
  68439. return \true;
  68440. }
  68441. /**
  68442. * @psalm-return class-string
  68443. */
  68444. public function className(): string
  68445. {
  68446. return $this->className;
  68447. }
  68448. /**
  68449. * @psalm-return non-empty-string
  68450. */
  68451. public function propertyName(): string
  68452. {
  68453. return $this->propertyName;
  68454. }
  68455. }
  68456. <?php
  68457. declare (strict_types=1);
  68458. /*
  68459. * This file is part of PHPUnit.
  68460. *
  68461. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68462. *
  68463. * For the full copyright and license information, please view the LICENSE
  68464. * file that was distributed with this source code.
  68465. */
  68466. namespace PHPUnit\Metadata;
  68467. /**
  68468. * @psalm-immutable
  68469. *
  68470. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68471. */
  68472. final class Group extends \PHPUnit\Metadata\Metadata
  68473. {
  68474. /**
  68475. * @psalm-var non-empty-string
  68476. */
  68477. private readonly string $groupName;
  68478. /**
  68479. * @psalm-param 0|1 $level
  68480. * @psalm-param non-empty-string $groupName
  68481. */
  68482. protected function __construct(int $level, string $groupName)
  68483. {
  68484. parent::__construct($level);
  68485. $this->groupName = $groupName;
  68486. }
  68487. /**
  68488. * @psalm-assert-if-true Group $this
  68489. */
  68490. public function isGroup(): bool
  68491. {
  68492. return \true;
  68493. }
  68494. /**
  68495. * @psalm-return non-empty-string
  68496. */
  68497. public function groupName(): string
  68498. {
  68499. return $this->groupName;
  68500. }
  68501. }
  68502. <?php
  68503. declare (strict_types=1);
  68504. /*
  68505. * This file is part of PHPUnit.
  68506. *
  68507. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68508. *
  68509. * For the full copyright and license information, please view the LICENSE
  68510. * file that was distributed with this source code.
  68511. */
  68512. namespace PHPUnit\Metadata;
  68513. /**
  68514. * @psalm-immutable
  68515. *
  68516. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68517. *
  68518. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  68519. */
  68520. final class IgnoreClassForCodeCoverage extends \PHPUnit\Metadata\Metadata
  68521. {
  68522. /**
  68523. * @psalm-var class-string
  68524. */
  68525. private readonly string $className;
  68526. /**
  68527. * @psalm-param 0|1 $level
  68528. * @psalm-param class-string $className
  68529. */
  68530. protected function __construct(int $level, string $className)
  68531. {
  68532. parent::__construct($level);
  68533. $this->className = $className;
  68534. }
  68535. /**
  68536. * @psalm-assert-if-true IgnoreClassForCodeCoverage $this
  68537. */
  68538. public function isIgnoreClassForCodeCoverage(): bool
  68539. {
  68540. return \true;
  68541. }
  68542. /**
  68543. * @psalm-return class-string
  68544. */
  68545. public function className(): string
  68546. {
  68547. return $this->className;
  68548. }
  68549. }
  68550. <?php
  68551. declare (strict_types=1);
  68552. /*
  68553. * This file is part of PHPUnit.
  68554. *
  68555. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68556. *
  68557. * For the full copyright and license information, please view the LICENSE
  68558. * file that was distributed with this source code.
  68559. */
  68560. namespace PHPUnit\Metadata;
  68561. /**
  68562. * @psalm-immutable
  68563. *
  68564. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68565. */
  68566. final class IgnoreDeprecations extends \PHPUnit\Metadata\Metadata
  68567. {
  68568. /**
  68569. * @psalm-assert-if-true IgnoreDeprecations $this
  68570. */
  68571. public function isIgnoreDeprecations(): bool
  68572. {
  68573. return \true;
  68574. }
  68575. }
  68576. <?php
  68577. declare (strict_types=1);
  68578. /*
  68579. * This file is part of PHPUnit.
  68580. *
  68581. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68582. *
  68583. * For the full copyright and license information, please view the LICENSE
  68584. * file that was distributed with this source code.
  68585. */
  68586. namespace PHPUnit\Metadata;
  68587. /**
  68588. * @psalm-immutable
  68589. *
  68590. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68591. *
  68592. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  68593. */
  68594. final class IgnoreFunctionForCodeCoverage extends \PHPUnit\Metadata\Metadata
  68595. {
  68596. /**
  68597. * @psalm-var non-empty-string
  68598. */
  68599. private readonly string $functionName;
  68600. /**
  68601. * @psalm-param 0|1 $level
  68602. * @psalm-param non-empty-string $functionName
  68603. */
  68604. protected function __construct(int $level, string $functionName)
  68605. {
  68606. parent::__construct($level);
  68607. $this->functionName = $functionName;
  68608. }
  68609. /**
  68610. * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this
  68611. */
  68612. public function isIgnoreFunctionForCodeCoverage(): bool
  68613. {
  68614. return \true;
  68615. }
  68616. /**
  68617. * @psalm-return non-empty-string
  68618. */
  68619. public function functionName(): string
  68620. {
  68621. return $this->functionName;
  68622. }
  68623. }
  68624. <?php
  68625. declare (strict_types=1);
  68626. /*
  68627. * This file is part of PHPUnit.
  68628. *
  68629. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68630. *
  68631. * For the full copyright and license information, please view the LICENSE
  68632. * file that was distributed with this source code.
  68633. */
  68634. namespace PHPUnit\Metadata;
  68635. /**
  68636. * @psalm-immutable
  68637. *
  68638. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68639. *
  68640. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  68641. */
  68642. final class IgnoreMethodForCodeCoverage extends \PHPUnit\Metadata\Metadata
  68643. {
  68644. /**
  68645. * @psalm-var class-string
  68646. */
  68647. private readonly string $className;
  68648. /**
  68649. * @psalm-var non-empty-string
  68650. */
  68651. private readonly string $methodName;
  68652. /**
  68653. * @psalm-param 0|1 $level
  68654. * @psalm-param class-string $className
  68655. * @psalm-param non-empty-string $methodName
  68656. */
  68657. protected function __construct(int $level, string $className, string $methodName)
  68658. {
  68659. parent::__construct($level);
  68660. $this->className = $className;
  68661. $this->methodName = $methodName;
  68662. }
  68663. /**
  68664. * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this
  68665. */
  68666. public function isIgnoreMethodForCodeCoverage(): bool
  68667. {
  68668. return \true;
  68669. }
  68670. /**
  68671. * @psalm-return class-string
  68672. */
  68673. public function className(): string
  68674. {
  68675. return $this->className;
  68676. }
  68677. /**
  68678. * @psalm-return non-empty-string
  68679. */
  68680. public function methodName(): string
  68681. {
  68682. return $this->methodName;
  68683. }
  68684. }
  68685. <?php
  68686. declare (strict_types=1);
  68687. /*
  68688. * This file is part of PHPUnit.
  68689. *
  68690. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  68691. *
  68692. * For the full copyright and license information, please view the LICENSE
  68693. * file that was distributed with this source code.
  68694. */
  68695. namespace PHPUnit\Metadata;
  68696. use PHPUnit\Metadata\Version\Requirement;
  68697. /**
  68698. * @psalm-immutable
  68699. *
  68700. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  68701. */
  68702. abstract class Metadata
  68703. {
  68704. private const CLASS_LEVEL = 0;
  68705. private const METHOD_LEVEL = 1;
  68706. /**
  68707. * @psalm-var 0|1
  68708. */
  68709. private readonly int $level;
  68710. public static function after(): \PHPUnit\Metadata\After
  68711. {
  68712. return new \PHPUnit\Metadata\After(self::METHOD_LEVEL);
  68713. }
  68714. public static function afterClass(): \PHPUnit\Metadata\AfterClass
  68715. {
  68716. return new \PHPUnit\Metadata\AfterClass(self::METHOD_LEVEL);
  68717. }
  68718. public static function backupGlobalsOnClass(bool $enabled): \PHPUnit\Metadata\BackupGlobals
  68719. {
  68720. return new \PHPUnit\Metadata\BackupGlobals(self::CLASS_LEVEL, $enabled);
  68721. }
  68722. public static function backupGlobalsOnMethod(bool $enabled): \PHPUnit\Metadata\BackupGlobals
  68723. {
  68724. return new \PHPUnit\Metadata\BackupGlobals(self::METHOD_LEVEL, $enabled);
  68725. }
  68726. public static function backupStaticPropertiesOnClass(bool $enabled): \PHPUnit\Metadata\BackupStaticProperties
  68727. {
  68728. return new \PHPUnit\Metadata\BackupStaticProperties(self::CLASS_LEVEL, $enabled);
  68729. }
  68730. public static function backupStaticPropertiesOnMethod(bool $enabled): \PHPUnit\Metadata\BackupStaticProperties
  68731. {
  68732. return new \PHPUnit\Metadata\BackupStaticProperties(self::METHOD_LEVEL, $enabled);
  68733. }
  68734. public static function before(): \PHPUnit\Metadata\Before
  68735. {
  68736. return new \PHPUnit\Metadata\Before(self::METHOD_LEVEL);
  68737. }
  68738. public static function beforeClass(): \PHPUnit\Metadata\BeforeClass
  68739. {
  68740. return new \PHPUnit\Metadata\BeforeClass(self::METHOD_LEVEL);
  68741. }
  68742. /**
  68743. * @psalm-param class-string $className
  68744. */
  68745. public static function coversClass(string $className): \PHPUnit\Metadata\CoversClass
  68746. {
  68747. return new \PHPUnit\Metadata\CoversClass(self::CLASS_LEVEL, $className);
  68748. }
  68749. /**
  68750. * @psalm-param non-empty-string $functionName
  68751. */
  68752. public static function coversFunction(string $functionName): \PHPUnit\Metadata\CoversFunction
  68753. {
  68754. return new \PHPUnit\Metadata\CoversFunction(self::CLASS_LEVEL, $functionName);
  68755. }
  68756. /**
  68757. * @psalm-param non-empty-string $target
  68758. */
  68759. public static function coversOnClass(string $target): \PHPUnit\Metadata\Covers
  68760. {
  68761. return new \PHPUnit\Metadata\Covers(self::CLASS_LEVEL, $target);
  68762. }
  68763. /**
  68764. * @psalm-param non-empty-string $target
  68765. */
  68766. public static function coversOnMethod(string $target): \PHPUnit\Metadata\Covers
  68767. {
  68768. return new \PHPUnit\Metadata\Covers(self::METHOD_LEVEL, $target);
  68769. }
  68770. /**
  68771. * @psalm-param class-string $className
  68772. */
  68773. public static function coversDefaultClass(string $className): \PHPUnit\Metadata\CoversDefaultClass
  68774. {
  68775. return new \PHPUnit\Metadata\CoversDefaultClass(self::CLASS_LEVEL, $className);
  68776. }
  68777. public static function coversNothingOnClass(): \PHPUnit\Metadata\CoversNothing
  68778. {
  68779. return new \PHPUnit\Metadata\CoversNothing(self::CLASS_LEVEL);
  68780. }
  68781. public static function coversNothingOnMethod(): \PHPUnit\Metadata\CoversNothing
  68782. {
  68783. return new \PHPUnit\Metadata\CoversNothing(self::METHOD_LEVEL);
  68784. }
  68785. /**
  68786. * @psalm-param class-string $className
  68787. * @psalm-param non-empty-string $methodName
  68788. */
  68789. public static function dataProvider(string $className, string $methodName): \PHPUnit\Metadata\DataProvider
  68790. {
  68791. return new \PHPUnit\Metadata\DataProvider(self::METHOD_LEVEL, $className, $methodName);
  68792. }
  68793. /**
  68794. * @psalm-param class-string $className
  68795. */
  68796. public static function dependsOnClass(string $className, bool $deepClone, bool $shallowClone): \PHPUnit\Metadata\DependsOnClass
  68797. {
  68798. return new \PHPUnit\Metadata\DependsOnClass(self::METHOD_LEVEL, $className, $deepClone, $shallowClone);
  68799. }
  68800. /**
  68801. * @psalm-param class-string $className
  68802. * @psalm-param non-empty-string $methodName
  68803. */
  68804. public static function dependsOnMethod(string $className, string $methodName, bool $deepClone, bool $shallowClone): \PHPUnit\Metadata\DependsOnMethod
  68805. {
  68806. return new \PHPUnit\Metadata\DependsOnMethod(self::METHOD_LEVEL, $className, $methodName, $deepClone, $shallowClone);
  68807. }
  68808. public static function doesNotPerformAssertionsOnClass(): \PHPUnit\Metadata\DoesNotPerformAssertions
  68809. {
  68810. return new \PHPUnit\Metadata\DoesNotPerformAssertions(self::CLASS_LEVEL);
  68811. }
  68812. public static function doesNotPerformAssertionsOnMethod(): \PHPUnit\Metadata\DoesNotPerformAssertions
  68813. {
  68814. return new \PHPUnit\Metadata\DoesNotPerformAssertions(self::METHOD_LEVEL);
  68815. }
  68816. /**
  68817. * @psalm-param non-empty-string $globalVariableName
  68818. */
  68819. public static function excludeGlobalVariableFromBackupOnClass(string $globalVariableName): \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup
  68820. {
  68821. return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::CLASS_LEVEL, $globalVariableName);
  68822. }
  68823. /**
  68824. * @psalm-param non-empty-string $globalVariableName
  68825. */
  68826. public static function excludeGlobalVariableFromBackupOnMethod(string $globalVariableName): \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup
  68827. {
  68828. return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::METHOD_LEVEL, $globalVariableName);
  68829. }
  68830. /**
  68831. * @psalm-param class-string $className
  68832. * @psalm-param non-empty-string $propertyName
  68833. */
  68834. public static function excludeStaticPropertyFromBackupOnClass(string $className, string $propertyName): \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup
  68835. {
  68836. return new \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup(self::CLASS_LEVEL, $className, $propertyName);
  68837. }
  68838. /**
  68839. * @psalm-param class-string $className
  68840. * @psalm-param non-empty-string $propertyName
  68841. */
  68842. public static function excludeStaticPropertyFromBackupOnMethod(string $className, string $propertyName): \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup
  68843. {
  68844. return new \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup(self::METHOD_LEVEL, $className, $propertyName);
  68845. }
  68846. /**
  68847. * @psalm-param non-empty-string $groupName
  68848. */
  68849. public static function groupOnClass(string $groupName): \PHPUnit\Metadata\Group
  68850. {
  68851. return new \PHPUnit\Metadata\Group(self::CLASS_LEVEL, $groupName);
  68852. }
  68853. /**
  68854. * @psalm-param non-empty-string $groupName
  68855. */
  68856. public static function groupOnMethod(string $groupName): \PHPUnit\Metadata\Group
  68857. {
  68858. return new \PHPUnit\Metadata\Group(self::METHOD_LEVEL, $groupName);
  68859. }
  68860. public static function ignoreDeprecationsOnClass(): \PHPUnit\Metadata\IgnoreDeprecations
  68861. {
  68862. return new \PHPUnit\Metadata\IgnoreDeprecations(self::CLASS_LEVEL);
  68863. }
  68864. public static function ignoreDeprecationsOnMethod(): \PHPUnit\Metadata\IgnoreDeprecations
  68865. {
  68866. return new \PHPUnit\Metadata\IgnoreDeprecations(self::METHOD_LEVEL);
  68867. }
  68868. /**
  68869. * @psalm-param class-string $className
  68870. */
  68871. public static function ignoreClassForCodeCoverage(string $className): \PHPUnit\Metadata\IgnoreClassForCodeCoverage
  68872. {
  68873. return new \PHPUnit\Metadata\IgnoreClassForCodeCoverage(self::CLASS_LEVEL, $className);
  68874. }
  68875. /**
  68876. * @psalm-param class-string $className
  68877. * @psalm-param non-empty-string $methodName
  68878. */
  68879. public static function ignoreMethodForCodeCoverage(string $className, string $methodName): \PHPUnit\Metadata\IgnoreMethodForCodeCoverage
  68880. {
  68881. return new \PHPUnit\Metadata\IgnoreMethodForCodeCoverage(self::CLASS_LEVEL, $className, $methodName);
  68882. }
  68883. /**
  68884. * @psalm-param non-empty-string $functionName
  68885. */
  68886. public static function ignoreFunctionForCodeCoverage(string $functionName): \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage
  68887. {
  68888. return new \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage(self::CLASS_LEVEL, $functionName);
  68889. }
  68890. public static function postCondition(): \PHPUnit\Metadata\PostCondition
  68891. {
  68892. return new \PHPUnit\Metadata\PostCondition(self::METHOD_LEVEL);
  68893. }
  68894. public static function preCondition(): \PHPUnit\Metadata\PreCondition
  68895. {
  68896. return new \PHPUnit\Metadata\PreCondition(self::METHOD_LEVEL);
  68897. }
  68898. public static function preserveGlobalStateOnClass(bool $enabled): \PHPUnit\Metadata\PreserveGlobalState
  68899. {
  68900. return new \PHPUnit\Metadata\PreserveGlobalState(self::CLASS_LEVEL, $enabled);
  68901. }
  68902. public static function preserveGlobalStateOnMethod(bool $enabled): \PHPUnit\Metadata\PreserveGlobalState
  68903. {
  68904. return new \PHPUnit\Metadata\PreserveGlobalState(self::METHOD_LEVEL, $enabled);
  68905. }
  68906. /**
  68907. * @psalm-param non-empty-string $functionName
  68908. */
  68909. public static function requiresFunctionOnClass(string $functionName): \PHPUnit\Metadata\RequiresFunction
  68910. {
  68911. return new \PHPUnit\Metadata\RequiresFunction(self::CLASS_LEVEL, $functionName);
  68912. }
  68913. /**
  68914. * @psalm-param non-empty-string $functionName
  68915. */
  68916. public static function requiresFunctionOnMethod(string $functionName): \PHPUnit\Metadata\RequiresFunction
  68917. {
  68918. return new \PHPUnit\Metadata\RequiresFunction(self::METHOD_LEVEL, $functionName);
  68919. }
  68920. /**
  68921. * @psalm-param class-string $className
  68922. * @psalm-param non-empty-string $methodName
  68923. */
  68924. public static function requiresMethodOnClass(string $className, string $methodName): \PHPUnit\Metadata\RequiresMethod
  68925. {
  68926. return new \PHPUnit\Metadata\RequiresMethod(self::CLASS_LEVEL, $className, $methodName);
  68927. }
  68928. /**
  68929. * @psalm-param class-string $className
  68930. * @psalm-param non-empty-string $methodName
  68931. */
  68932. public static function requiresMethodOnMethod(string $className, string $methodName): \PHPUnit\Metadata\RequiresMethod
  68933. {
  68934. return new \PHPUnit\Metadata\RequiresMethod(self::METHOD_LEVEL, $className, $methodName);
  68935. }
  68936. /**
  68937. * @psalm-param non-empty-string $operatingSystem
  68938. */
  68939. public static function requiresOperatingSystemOnClass(string $operatingSystem): \PHPUnit\Metadata\RequiresOperatingSystem
  68940. {
  68941. return new \PHPUnit\Metadata\RequiresOperatingSystem(self::CLASS_LEVEL, $operatingSystem);
  68942. }
  68943. /**
  68944. * @psalm-param non-empty-string $operatingSystem
  68945. */
  68946. public static function requiresOperatingSystemOnMethod(string $operatingSystem): \PHPUnit\Metadata\RequiresOperatingSystem
  68947. {
  68948. return new \PHPUnit\Metadata\RequiresOperatingSystem(self::METHOD_LEVEL, $operatingSystem);
  68949. }
  68950. /**
  68951. * @psalm-param non-empty-string $operatingSystemFamily
  68952. */
  68953. public static function requiresOperatingSystemFamilyOnClass(string $operatingSystemFamily): \PHPUnit\Metadata\RequiresOperatingSystemFamily
  68954. {
  68955. return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::CLASS_LEVEL, $operatingSystemFamily);
  68956. }
  68957. /**
  68958. * @psalm-param non-empty-string $operatingSystemFamily
  68959. */
  68960. public static function requiresOperatingSystemFamilyOnMethod(string $operatingSystemFamily): \PHPUnit\Metadata\RequiresOperatingSystemFamily
  68961. {
  68962. return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::METHOD_LEVEL, $operatingSystemFamily);
  68963. }
  68964. public static function requiresPhpOnClass(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhp
  68965. {
  68966. return new \PHPUnit\Metadata\RequiresPhp(self::CLASS_LEVEL, $versionRequirement);
  68967. }
  68968. public static function requiresPhpOnMethod(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhp
  68969. {
  68970. return new \PHPUnit\Metadata\RequiresPhp(self::METHOD_LEVEL, $versionRequirement);
  68971. }
  68972. /**
  68973. * @psalm-param non-empty-string $extension
  68974. */
  68975. public static function requiresPhpExtensionOnClass(string $extension, ?Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpExtension
  68976. {
  68977. return new \PHPUnit\Metadata\RequiresPhpExtension(self::CLASS_LEVEL, $extension, $versionRequirement);
  68978. }
  68979. /**
  68980. * @psalm-param non-empty-string $extension
  68981. */
  68982. public static function requiresPhpExtensionOnMethod(string $extension, ?Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpExtension
  68983. {
  68984. return new \PHPUnit\Metadata\RequiresPhpExtension(self::METHOD_LEVEL, $extension, $versionRequirement);
  68985. }
  68986. public static function requiresPhpunitOnClass(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpunit
  68987. {
  68988. return new \PHPUnit\Metadata\RequiresPhpunit(self::CLASS_LEVEL, $versionRequirement);
  68989. }
  68990. public static function requiresPhpunitOnMethod(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpunit
  68991. {
  68992. return new \PHPUnit\Metadata\RequiresPhpunit(self::METHOD_LEVEL, $versionRequirement);
  68993. }
  68994. /**
  68995. * @psalm-param non-empty-string $setting
  68996. * @psalm-param non-empty-string $value
  68997. */
  68998. public static function requiresSettingOnClass(string $setting, string $value): \PHPUnit\Metadata\RequiresSetting
  68999. {
  69000. return new \PHPUnit\Metadata\RequiresSetting(self::CLASS_LEVEL, $setting, $value);
  69001. }
  69002. /**
  69003. * @psalm-param non-empty-string $setting
  69004. * @psalm-param non-empty-string $value
  69005. */
  69006. public static function requiresSettingOnMethod(string $setting, string $value): \PHPUnit\Metadata\RequiresSetting
  69007. {
  69008. return new \PHPUnit\Metadata\RequiresSetting(self::METHOD_LEVEL, $setting, $value);
  69009. }
  69010. public static function runClassInSeparateProcess(): \PHPUnit\Metadata\RunClassInSeparateProcess
  69011. {
  69012. return new \PHPUnit\Metadata\RunClassInSeparateProcess(self::CLASS_LEVEL);
  69013. }
  69014. public static function runTestsInSeparateProcesses(): \PHPUnit\Metadata\RunTestsInSeparateProcesses
  69015. {
  69016. return new \PHPUnit\Metadata\RunTestsInSeparateProcesses(self::CLASS_LEVEL);
  69017. }
  69018. public static function runInSeparateProcess(): \PHPUnit\Metadata\RunInSeparateProcess
  69019. {
  69020. return new \PHPUnit\Metadata\RunInSeparateProcess(self::METHOD_LEVEL);
  69021. }
  69022. public static function test(): \PHPUnit\Metadata\Test
  69023. {
  69024. return new \PHPUnit\Metadata\Test(self::METHOD_LEVEL);
  69025. }
  69026. /**
  69027. * @psalm-param non-empty-string $text
  69028. */
  69029. public static function testDoxOnClass(string $text): \PHPUnit\Metadata\TestDox
  69030. {
  69031. return new \PHPUnit\Metadata\TestDox(self::CLASS_LEVEL, $text);
  69032. }
  69033. /**
  69034. * @psalm-param non-empty-string $text
  69035. */
  69036. public static function testDoxOnMethod(string $text): \PHPUnit\Metadata\TestDox
  69037. {
  69038. return new \PHPUnit\Metadata\TestDox(self::METHOD_LEVEL, $text);
  69039. }
  69040. public static function testWith(array $data): \PHPUnit\Metadata\TestWith
  69041. {
  69042. return new \PHPUnit\Metadata\TestWith(self::METHOD_LEVEL, $data);
  69043. }
  69044. /**
  69045. * @psalm-param class-string $className
  69046. */
  69047. public static function usesClass(string $className): \PHPUnit\Metadata\UsesClass
  69048. {
  69049. return new \PHPUnit\Metadata\UsesClass(self::CLASS_LEVEL, $className);
  69050. }
  69051. /**
  69052. * @psalm-param non-empty-string $functionName
  69053. */
  69054. public static function usesFunction(string $functionName): \PHPUnit\Metadata\UsesFunction
  69055. {
  69056. return new \PHPUnit\Metadata\UsesFunction(self::CLASS_LEVEL, $functionName);
  69057. }
  69058. /**
  69059. * @psalm-param non-empty-string $target
  69060. */
  69061. public static function usesOnClass(string $target): \PHPUnit\Metadata\Uses
  69062. {
  69063. return new \PHPUnit\Metadata\Uses(self::CLASS_LEVEL, $target);
  69064. }
  69065. /**
  69066. * @psalm-param non-empty-string $target
  69067. */
  69068. public static function usesOnMethod(string $target): \PHPUnit\Metadata\Uses
  69069. {
  69070. return new \PHPUnit\Metadata\Uses(self::METHOD_LEVEL, $target);
  69071. }
  69072. /**
  69073. * @psalm-param class-string $className
  69074. */
  69075. public static function usesDefaultClass(string $className): \PHPUnit\Metadata\UsesDefaultClass
  69076. {
  69077. return new \PHPUnit\Metadata\UsesDefaultClass(self::CLASS_LEVEL, $className);
  69078. }
  69079. public static function withoutErrorHandler(): \PHPUnit\Metadata\WithoutErrorHandler
  69080. {
  69081. return new \PHPUnit\Metadata\WithoutErrorHandler(self::METHOD_LEVEL);
  69082. }
  69083. /**
  69084. * @psalm-param 0|1 $level
  69085. */
  69086. protected function __construct(int $level)
  69087. {
  69088. $this->level = $level;
  69089. }
  69090. public function isClassLevel(): bool
  69091. {
  69092. return $this->level === self::CLASS_LEVEL;
  69093. }
  69094. public function isMethodLevel(): bool
  69095. {
  69096. return $this->level === self::METHOD_LEVEL;
  69097. }
  69098. /**
  69099. * @psalm-assert-if-true After $this
  69100. */
  69101. public function isAfter(): bool
  69102. {
  69103. return \false;
  69104. }
  69105. /**
  69106. * @psalm-assert-if-true AfterClass $this
  69107. */
  69108. public function isAfterClass(): bool
  69109. {
  69110. return \false;
  69111. }
  69112. /**
  69113. * @psalm-assert-if-true BackupGlobals $this
  69114. */
  69115. public function isBackupGlobals(): bool
  69116. {
  69117. return \false;
  69118. }
  69119. /**
  69120. * @psalm-assert-if-true BackupStaticProperties $this
  69121. */
  69122. public function isBackupStaticProperties(): bool
  69123. {
  69124. return \false;
  69125. }
  69126. /**
  69127. * @psalm-assert-if-true BeforeClass $this
  69128. */
  69129. public function isBeforeClass(): bool
  69130. {
  69131. return \false;
  69132. }
  69133. /**
  69134. * @psalm-assert-if-true Before $this
  69135. */
  69136. public function isBefore(): bool
  69137. {
  69138. return \false;
  69139. }
  69140. /**
  69141. * @psalm-assert-if-true Covers $this
  69142. */
  69143. public function isCovers(): bool
  69144. {
  69145. return \false;
  69146. }
  69147. /**
  69148. * @psalm-assert-if-true CoversClass $this
  69149. */
  69150. public function isCoversClass(): bool
  69151. {
  69152. return \false;
  69153. }
  69154. /**
  69155. * @psalm-assert-if-true CoversDefaultClass $this
  69156. */
  69157. public function isCoversDefaultClass(): bool
  69158. {
  69159. return \false;
  69160. }
  69161. /**
  69162. * @psalm-assert-if-true CoversFunction $this
  69163. */
  69164. public function isCoversFunction(): bool
  69165. {
  69166. return \false;
  69167. }
  69168. /**
  69169. * @psalm-assert-if-true CoversNothing $this
  69170. */
  69171. public function isCoversNothing(): bool
  69172. {
  69173. return \false;
  69174. }
  69175. /**
  69176. * @psalm-assert-if-true DataProvider $this
  69177. */
  69178. public function isDataProvider(): bool
  69179. {
  69180. return \false;
  69181. }
  69182. /**
  69183. * @psalm-assert-if-true DependsOnClass $this
  69184. */
  69185. public function isDependsOnClass(): bool
  69186. {
  69187. return \false;
  69188. }
  69189. /**
  69190. * @psalm-assert-if-true DependsOnMethod $this
  69191. */
  69192. public function isDependsOnMethod(): bool
  69193. {
  69194. return \false;
  69195. }
  69196. /**
  69197. * @psalm-assert-if-true DoesNotPerformAssertions $this
  69198. */
  69199. public function isDoesNotPerformAssertions(): bool
  69200. {
  69201. return \false;
  69202. }
  69203. /**
  69204. * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this
  69205. */
  69206. public function isExcludeGlobalVariableFromBackup(): bool
  69207. {
  69208. return \false;
  69209. }
  69210. /**
  69211. * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this
  69212. */
  69213. public function isExcludeStaticPropertyFromBackup(): bool
  69214. {
  69215. return \false;
  69216. }
  69217. /**
  69218. * @psalm-assert-if-true Group $this
  69219. */
  69220. public function isGroup(): bool
  69221. {
  69222. return \false;
  69223. }
  69224. /**
  69225. * @psalm-assert-if-true IgnoreDeprecations $this
  69226. */
  69227. public function isIgnoreDeprecations(): bool
  69228. {
  69229. return \false;
  69230. }
  69231. /**
  69232. * @psalm-assert-if-true IgnoreClassForCodeCoverage $this
  69233. */
  69234. public function isIgnoreClassForCodeCoverage(): bool
  69235. {
  69236. return \false;
  69237. }
  69238. /**
  69239. * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this
  69240. */
  69241. public function isIgnoreMethodForCodeCoverage(): bool
  69242. {
  69243. return \false;
  69244. }
  69245. /**
  69246. * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this
  69247. */
  69248. public function isIgnoreFunctionForCodeCoverage(): bool
  69249. {
  69250. return \false;
  69251. }
  69252. /**
  69253. * @psalm-assert-if-true RunClassInSeparateProcess $this
  69254. */
  69255. public function isRunClassInSeparateProcess(): bool
  69256. {
  69257. return \false;
  69258. }
  69259. /**
  69260. * @psalm-assert-if-true RunInSeparateProcess $this
  69261. */
  69262. public function isRunInSeparateProcess(): bool
  69263. {
  69264. return \false;
  69265. }
  69266. /**
  69267. * @psalm-assert-if-true RunTestsInSeparateProcesses $this
  69268. */
  69269. public function isRunTestsInSeparateProcesses(): bool
  69270. {
  69271. return \false;
  69272. }
  69273. /**
  69274. * @psalm-assert-if-true Test $this
  69275. */
  69276. public function isTest(): bool
  69277. {
  69278. return \false;
  69279. }
  69280. /**
  69281. * @psalm-assert-if-true PreCondition $this
  69282. */
  69283. public function isPreCondition(): bool
  69284. {
  69285. return \false;
  69286. }
  69287. /**
  69288. * @psalm-assert-if-true PostCondition $this
  69289. */
  69290. public function isPostCondition(): bool
  69291. {
  69292. return \false;
  69293. }
  69294. /**
  69295. * @psalm-assert-if-true PreserveGlobalState $this
  69296. */
  69297. public function isPreserveGlobalState(): bool
  69298. {
  69299. return \false;
  69300. }
  69301. /**
  69302. * @psalm-assert-if-true RequiresMethod $this
  69303. */
  69304. public function isRequiresMethod(): bool
  69305. {
  69306. return \false;
  69307. }
  69308. /**
  69309. * @psalm-assert-if-true RequiresFunction $this
  69310. */
  69311. public function isRequiresFunction(): bool
  69312. {
  69313. return \false;
  69314. }
  69315. /**
  69316. * @psalm-assert-if-true RequiresOperatingSystem $this
  69317. */
  69318. public function isRequiresOperatingSystem(): bool
  69319. {
  69320. return \false;
  69321. }
  69322. /**
  69323. * @psalm-assert-if-true RequiresOperatingSystemFamily $this
  69324. */
  69325. public function isRequiresOperatingSystemFamily(): bool
  69326. {
  69327. return \false;
  69328. }
  69329. /**
  69330. * @psalm-assert-if-true RequiresPhp $this
  69331. */
  69332. public function isRequiresPhp(): bool
  69333. {
  69334. return \false;
  69335. }
  69336. /**
  69337. * @psalm-assert-if-true RequiresPhpExtension $this
  69338. */
  69339. public function isRequiresPhpExtension(): bool
  69340. {
  69341. return \false;
  69342. }
  69343. /**
  69344. * @psalm-assert-if-true RequiresPhpunit $this
  69345. */
  69346. public function isRequiresPhpunit(): bool
  69347. {
  69348. return \false;
  69349. }
  69350. /**
  69351. * @psalm-assert-if-true RequiresSetting $this
  69352. */
  69353. public function isRequiresSetting(): bool
  69354. {
  69355. return \false;
  69356. }
  69357. /**
  69358. * @psalm-assert-if-true TestDox $this
  69359. */
  69360. public function isTestDox(): bool
  69361. {
  69362. return \false;
  69363. }
  69364. /**
  69365. * @psalm-assert-if-true TestWith $this
  69366. */
  69367. public function isTestWith(): bool
  69368. {
  69369. return \false;
  69370. }
  69371. /**
  69372. * @psalm-assert-if-true Uses $this
  69373. */
  69374. public function isUses(): bool
  69375. {
  69376. return \false;
  69377. }
  69378. /**
  69379. * @psalm-assert-if-true UsesClass $this
  69380. */
  69381. public function isUsesClass(): bool
  69382. {
  69383. return \false;
  69384. }
  69385. /**
  69386. * @psalm-assert-if-true UsesDefaultClass $this
  69387. */
  69388. public function isUsesDefaultClass(): bool
  69389. {
  69390. return \false;
  69391. }
  69392. /**
  69393. * @psalm-assert-if-true UsesFunction $this
  69394. */
  69395. public function isUsesFunction(): bool
  69396. {
  69397. return \false;
  69398. }
  69399. /**
  69400. * @psalm-assert-if-true WithoutErrorHandler $this
  69401. */
  69402. public function isWithoutErrorHandler(): bool
  69403. {
  69404. return \false;
  69405. }
  69406. }
  69407. <?php
  69408. declare (strict_types=1);
  69409. /*
  69410. * This file is part of PHPUnit.
  69411. *
  69412. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  69413. *
  69414. * For the full copyright and license information, please view the LICENSE
  69415. * file that was distributed with this source code.
  69416. */
  69417. namespace PHPUnit\Metadata;
  69418. use function array_filter;
  69419. use function array_merge;
  69420. use function count;
  69421. use Countable;
  69422. use IteratorAggregate;
  69423. /**
  69424. * @template-implements IteratorAggregate<int, Metadata>
  69425. *
  69426. * @psalm-immutable
  69427. *
  69428. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  69429. */
  69430. final class MetadataCollection implements Countable, IteratorAggregate
  69431. {
  69432. /**
  69433. * @psalm-var list<Metadata>
  69434. */
  69435. private readonly array $metadata;
  69436. /**
  69437. * @psalm-param list<Metadata> $metadata
  69438. */
  69439. public static function fromArray(array $metadata): self
  69440. {
  69441. return new self(...$metadata);
  69442. }
  69443. private function __construct(\PHPUnit\Metadata\Metadata ...$metadata)
  69444. {
  69445. $this->metadata = $metadata;
  69446. }
  69447. /**
  69448. * @psalm-return list<Metadata>
  69449. */
  69450. public function asArray(): array
  69451. {
  69452. return $this->metadata;
  69453. }
  69454. public function count(): int
  69455. {
  69456. return count($this->metadata);
  69457. }
  69458. public function isEmpty(): bool
  69459. {
  69460. return $this->count() === 0;
  69461. }
  69462. public function isNotEmpty(): bool
  69463. {
  69464. return $this->count() > 0;
  69465. }
  69466. public function getIterator(): \PHPUnit\Metadata\MetadataCollectionIterator
  69467. {
  69468. return new \PHPUnit\Metadata\MetadataCollectionIterator($this);
  69469. }
  69470. public function mergeWith(self $other): self
  69471. {
  69472. return new self(...array_merge($this->asArray(), $other->asArray()));
  69473. }
  69474. public function isClassLevel(): self
  69475. {
  69476. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isClassLevel()));
  69477. }
  69478. public function isMethodLevel(): self
  69479. {
  69480. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isMethodLevel()));
  69481. }
  69482. public function isAfter(): self
  69483. {
  69484. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isAfter()));
  69485. }
  69486. public function isAfterClass(): self
  69487. {
  69488. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isAfterClass()));
  69489. }
  69490. public function isBackupGlobals(): self
  69491. {
  69492. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBackupGlobals()));
  69493. }
  69494. public function isBackupStaticProperties(): self
  69495. {
  69496. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBackupStaticProperties()));
  69497. }
  69498. public function isBeforeClass(): self
  69499. {
  69500. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBeforeClass()));
  69501. }
  69502. public function isBefore(): self
  69503. {
  69504. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBefore()));
  69505. }
  69506. public function isCovers(): self
  69507. {
  69508. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCovers()));
  69509. }
  69510. public function isCoversClass(): self
  69511. {
  69512. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversClass()));
  69513. }
  69514. public function isCoversDefaultClass(): self
  69515. {
  69516. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversDefaultClass()));
  69517. }
  69518. public function isCoversFunction(): self
  69519. {
  69520. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversFunction()));
  69521. }
  69522. public function isExcludeGlobalVariableFromBackup(): self
  69523. {
  69524. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isExcludeGlobalVariableFromBackup()));
  69525. }
  69526. public function isExcludeStaticPropertyFromBackup(): self
  69527. {
  69528. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isExcludeStaticPropertyFromBackup()));
  69529. }
  69530. public function isCoversNothing(): self
  69531. {
  69532. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversNothing()));
  69533. }
  69534. public function isDataProvider(): self
  69535. {
  69536. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDataProvider()));
  69537. }
  69538. public function isDepends(): self
  69539. {
  69540. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnClass() || $metadata->isDependsOnMethod()));
  69541. }
  69542. public function isDependsOnClass(): self
  69543. {
  69544. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnClass()));
  69545. }
  69546. public function isDependsOnMethod(): self
  69547. {
  69548. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnMethod()));
  69549. }
  69550. public function isDoesNotPerformAssertions(): self
  69551. {
  69552. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDoesNotPerformAssertions()));
  69553. }
  69554. public function isGroup(): self
  69555. {
  69556. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isGroup()));
  69557. }
  69558. public function isIgnoreDeprecations(): self
  69559. {
  69560. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreDeprecations()));
  69561. }
  69562. /**
  69563. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  69564. */
  69565. public function isIgnoreClassForCodeCoverage(): self
  69566. {
  69567. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreClassForCodeCoverage()));
  69568. }
  69569. /**
  69570. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  69571. */
  69572. public function isIgnoreMethodForCodeCoverage(): self
  69573. {
  69574. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreMethodForCodeCoverage()));
  69575. }
  69576. /**
  69577. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
  69578. */
  69579. public function isIgnoreFunctionForCodeCoverage(): self
  69580. {
  69581. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreFunctionForCodeCoverage()));
  69582. }
  69583. public function isRunClassInSeparateProcess(): self
  69584. {
  69585. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunClassInSeparateProcess()));
  69586. }
  69587. public function isRunInSeparateProcess(): self
  69588. {
  69589. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunInSeparateProcess()));
  69590. }
  69591. public function isRunTestsInSeparateProcesses(): self
  69592. {
  69593. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunTestsInSeparateProcesses()));
  69594. }
  69595. public function isTest(): self
  69596. {
  69597. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTest()));
  69598. }
  69599. public function isPreCondition(): self
  69600. {
  69601. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPreCondition()));
  69602. }
  69603. public function isPostCondition(): self
  69604. {
  69605. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPostCondition()));
  69606. }
  69607. public function isPreserveGlobalState(): self
  69608. {
  69609. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPreserveGlobalState()));
  69610. }
  69611. public function isRequiresMethod(): self
  69612. {
  69613. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresMethod()));
  69614. }
  69615. public function isRequiresFunction(): self
  69616. {
  69617. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresFunction()));
  69618. }
  69619. public function isRequiresOperatingSystem(): self
  69620. {
  69621. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresOperatingSystem()));
  69622. }
  69623. public function isRequiresOperatingSystemFamily(): self
  69624. {
  69625. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresOperatingSystemFamily()));
  69626. }
  69627. public function isRequiresPhp(): self
  69628. {
  69629. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhp()));
  69630. }
  69631. public function isRequiresPhpExtension(): self
  69632. {
  69633. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhpExtension()));
  69634. }
  69635. public function isRequiresPhpunit(): self
  69636. {
  69637. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhpunit()));
  69638. }
  69639. public function isRequiresSetting(): self
  69640. {
  69641. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresSetting()));
  69642. }
  69643. public function isTestDox(): self
  69644. {
  69645. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTestDox()));
  69646. }
  69647. public function isTestWith(): self
  69648. {
  69649. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTestWith()));
  69650. }
  69651. public function isUses(): self
  69652. {
  69653. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUses()));
  69654. }
  69655. public function isUsesClass(): self
  69656. {
  69657. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesClass()));
  69658. }
  69659. public function isUsesDefaultClass(): self
  69660. {
  69661. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesDefaultClass()));
  69662. }
  69663. public function isUsesFunction(): self
  69664. {
  69665. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesFunction()));
  69666. }
  69667. public function isWithoutErrorHandler(): self
  69668. {
  69669. return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isWithoutErrorHandler()));
  69670. }
  69671. }
  69672. <?php
  69673. declare (strict_types=1);
  69674. /*
  69675. * This file is part of PHPUnit.
  69676. *
  69677. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  69678. *
  69679. * For the full copyright and license information, please view the LICENSE
  69680. * file that was distributed with this source code.
  69681. */
  69682. namespace PHPUnit\Metadata;
  69683. use function count;
  69684. use Iterator;
  69685. /**
  69686. * @template-implements Iterator<int, Metadata>
  69687. *
  69688. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  69689. */
  69690. final class MetadataCollectionIterator implements Iterator
  69691. {
  69692. /**
  69693. * @psalm-var list<Metadata>
  69694. */
  69695. private readonly array $metadata;
  69696. private int $position = 0;
  69697. public function __construct(\PHPUnit\Metadata\MetadataCollection $metadata)
  69698. {
  69699. $this->metadata = $metadata->asArray();
  69700. }
  69701. public function rewind(): void
  69702. {
  69703. $this->position = 0;
  69704. }
  69705. public function valid(): bool
  69706. {
  69707. return $this->position < count($this->metadata);
  69708. }
  69709. public function key(): int
  69710. {
  69711. return $this->position;
  69712. }
  69713. public function current(): \PHPUnit\Metadata\Metadata
  69714. {
  69715. return $this->metadata[$this->position];
  69716. }
  69717. public function next(): void
  69718. {
  69719. $this->position++;
  69720. }
  69721. }
  69722. <?php
  69723. declare (strict_types=1);
  69724. /*
  69725. * This file is part of PHPUnit.
  69726. *
  69727. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  69728. *
  69729. * For the full copyright and license information, please view the LICENSE
  69730. * file that was distributed with this source code.
  69731. */
  69732. namespace PHPUnit\Metadata\Annotation\Parser;
  69733. use function array_filter;
  69734. use function array_map;
  69735. use function array_merge;
  69736. use function array_values;
  69737. use function count;
  69738. use function preg_match;
  69739. use function preg_match_all;
  69740. use function preg_replace;
  69741. use function preg_split;
  69742. use function realpath;
  69743. use function substr;
  69744. use function trim;
  69745. use PHPUnitPHAR\PharIo\Version\Exception as PharIoVersionException;
  69746. use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
  69747. use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
  69748. use PHPUnit\Metadata\InvalidVersionRequirementException;
  69749. use ReflectionClass;
  69750. use ReflectionFunctionAbstract;
  69751. use ReflectionMethod;
  69752. /**
  69753. * This is an abstraction around a PHPUnit-specific docBlock,
  69754. * allowing us to ask meaningful questions about a specific
  69755. * reflection symbol.
  69756. *
  69757. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  69758. *
  69759. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  69760. */
  69761. final class DocBlock
  69762. {
  69763. private const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
  69764. private const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<constraint>[\d\t \-.|~^]+)[ \t]*\r?$/m';
  69765. private const REGEX_REQUIRES_OS = '/@requires\s+(?P<name>OS(?:FAMILY)?)\s+(?P<value>.+?)[ \t]*\r?$/m';
  69766. private const REGEX_REQUIRES_SETTING = '/@requires\s+(?P<name>setting)\s+(?P<setting>([^ ]+?))\s*(?P<value>[\w\.-]+[\w\.]?)?[ \t]*\r?$/m';
  69767. private const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^\s<>=!]+))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m';
  69768. private readonly string $docComment;
  69769. /**
  69770. * @psalm-var array<string, array<int, string>> pre-parsed annotations indexed by name and occurrence index
  69771. */
  69772. private readonly array $symbolAnnotations;
  69773. /**
  69774. * @psalm-var null|(array{
  69775. * __OFFSET: array<string, int>&array{__FILE: string},
  69776. * setting?: array<string, string>,
  69777. * extension_versions?: array<string, array{version: string, operator: string}>
  69778. * }&array<
  69779. * string,
  69780. * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string>
  69781. * >)
  69782. */
  69783. private ?array $parsedRequirements = null;
  69784. private readonly int $startLine;
  69785. private readonly string $fileName;
  69786. /**
  69787. * @throws AnnotationsAreNotSupportedForInternalClassesException
  69788. */
  69789. public static function ofClass(ReflectionClass $class): self
  69790. {
  69791. if ($class->isInternal()) {
  69792. throw new AnnotationsAreNotSupportedForInternalClassesException($class->getName());
  69793. }
  69794. return new self((string) $class->getDocComment(), self::extractAnnotationsFromReflector($class), $class->getStartLine(), $class->getFileName());
  69795. }
  69796. /**
  69797. * @throws AnnotationsAreNotSupportedForInternalClassesException
  69798. */
  69799. public static function ofMethod(ReflectionMethod $method): self
  69800. {
  69801. if ($method->getDeclaringClass()->isInternal()) {
  69802. throw new AnnotationsAreNotSupportedForInternalClassesException($method->getDeclaringClass()->getName());
  69803. }
  69804. return new self((string) $method->getDocComment(), self::extractAnnotationsFromReflector($method), $method->getStartLine(), $method->getFileName());
  69805. }
  69806. /**
  69807. * Note: we do not preserve an instance of the reflection object, since it cannot be safely (de-)serialized.
  69808. *
  69809. * @param array<string, array<int, string>> $symbolAnnotations
  69810. */
  69811. private function __construct(string $docComment, array $symbolAnnotations, int $startLine, string $fileName)
  69812. {
  69813. $this->docComment = $docComment;
  69814. $this->symbolAnnotations = $symbolAnnotations;
  69815. $this->startLine = $startLine;
  69816. $this->fileName = $fileName;
  69817. }
  69818. /**
  69819. * @psalm-return array{
  69820. * __OFFSET: array<string, int>&array{__FILE: string},
  69821. * setting?: array<string, string>,
  69822. * extension_versions?: array<string, array{version: string, operator: string}>
  69823. * }&array<
  69824. * string,
  69825. * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string>
  69826. * >
  69827. *
  69828. * @throws InvalidVersionRequirementException
  69829. */
  69830. public function requirements(): array
  69831. {
  69832. if ($this->parsedRequirements !== null) {
  69833. return $this->parsedRequirements;
  69834. }
  69835. $offset = $this->startLine;
  69836. $requires = [];
  69837. $recordedSettings = [];
  69838. $extensionVersions = [];
  69839. $recordedOffsets = ['__FILE' => realpath($this->fileName)];
  69840. // Trim docblock markers, split it into lines and rewind offset to start of docblock
  69841. $lines = preg_replace(['#^/\*{2}#', '#\*/$#'], '', preg_split('/\r\n|\r|\n/', $this->docComment));
  69842. $offset -= count($lines);
  69843. foreach ($lines as $line) {
  69844. if (preg_match(self::REGEX_REQUIRES_OS, $line, $matches)) {
  69845. $requires[$matches['name']] = $matches['value'];
  69846. $recordedOffsets[$matches['name']] = $offset;
  69847. }
  69848. if (preg_match(self::REGEX_REQUIRES_VERSION, $line, $matches)) {
  69849. $requires[$matches['name']] = ['version' => $matches['version'], 'operator' => $matches['operator']];
  69850. $recordedOffsets[$matches['name']] = $offset;
  69851. }
  69852. if (preg_match(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $line, $matches)) {
  69853. if (!empty($requires[$matches['name']])) {
  69854. $offset++;
  69855. continue;
  69856. }
  69857. try {
  69858. $versionConstraintParser = new VersionConstraintParser();
  69859. $requires[$matches['name'] . '_constraint'] = ['constraint' => $versionConstraintParser->parse(trim($matches['constraint']))];
  69860. $recordedOffsets[$matches['name'] . '_constraint'] = $offset;
  69861. } catch (PharIoVersionException $e) {
  69862. throw new InvalidVersionRequirementException($e->getMessage(), $e->getCode(), $e);
  69863. }
  69864. }
  69865. if (preg_match(self::REGEX_REQUIRES_SETTING, $line, $matches)) {
  69866. $recordedSettings[$matches['setting']] = $matches['value'];
  69867. $recordedOffsets['__SETTING_' . $matches['setting']] = $offset;
  69868. }
  69869. if (preg_match(self::REGEX_REQUIRES, $line, $matches)) {
  69870. $name = $matches['name'] . 's';
  69871. if (!isset($requires[$name])) {
  69872. $requires[$name] = [];
  69873. }
  69874. $requires[$name][] = $matches['value'];
  69875. $recordedOffsets[$matches['name'] . '_' . $matches['value']] = $offset;
  69876. if ($name === 'extensions' && !empty($matches['version'])) {
  69877. $extensionVersions[$matches['value']] = ['version' => $matches['version'], 'operator' => $matches['operator']];
  69878. }
  69879. }
  69880. $offset++;
  69881. }
  69882. return $this->parsedRequirements = array_merge($requires, ['__OFFSET' => $recordedOffsets], array_filter(['setting' => $recordedSettings, 'extension_versions' => $extensionVersions]));
  69883. }
  69884. public function symbolAnnotations(): array
  69885. {
  69886. return $this->symbolAnnotations;
  69887. }
  69888. /**
  69889. * @psalm-return array<string, array<int, string>>
  69890. */
  69891. private static function parseDocBlock(string $docBlock): array
  69892. {
  69893. // Strip away the docblock header and footer to ease parsing of one line annotations
  69894. $docBlock = substr($docBlock, 3, -2);
  69895. $annotations = [];
  69896. if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docBlock, $matches)) {
  69897. $numMatches = count($matches[0]);
  69898. for ($i = 0; $i < $numMatches; $i++) {
  69899. $annotations[$matches['name'][$i]][] = $matches['value'][$i];
  69900. }
  69901. }
  69902. return $annotations;
  69903. }
  69904. private static function extractAnnotationsFromReflector(ReflectionClass|ReflectionFunctionAbstract $reflector): array
  69905. {
  69906. $annotations = [];
  69907. if ($reflector instanceof ReflectionClass) {
  69908. $annotations = array_merge($annotations, ...array_map(static fn(ReflectionClass $trait): array => self::parseDocBlock((string) $trait->getDocComment()), array_values($reflector->getTraits())));
  69909. }
  69910. return array_merge($annotations, self::parseDocBlock((string) $reflector->getDocComment()));
  69911. }
  69912. }
  69913. <?php
  69914. declare (strict_types=1);
  69915. /*
  69916. * This file is part of PHPUnit.
  69917. *
  69918. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  69919. *
  69920. * For the full copyright and license information, please view the LICENSE
  69921. * file that was distributed with this source code.
  69922. */
  69923. namespace PHPUnit\Metadata\Annotation\Parser;
  69924. use function array_key_exists;
  69925. use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
  69926. use PHPUnit\Metadata\ReflectionException;
  69927. use ReflectionClass;
  69928. use ReflectionMethod;
  69929. /**
  69930. * Reflection information, and therefore DocBlock information, is static within
  69931. * a single PHP process. It is therefore okay to use a Singleton registry here.
  69932. *
  69933. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  69934. *
  69935. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  69936. */
  69937. final class Registry
  69938. {
  69939. private static ?\PHPUnit\Metadata\Annotation\Parser\Registry $instance = null;
  69940. /**
  69941. * @psalm-var array<string, DocBlock> indexed by class name
  69942. */
  69943. private array $classDocBlocks = [];
  69944. /**
  69945. * @psalm-var array<string, array<string, DocBlock>> indexed by class name and method name
  69946. */
  69947. private array $methodDocBlocks = [];
  69948. public static function getInstance(): self
  69949. {
  69950. return self::$instance ?? self::$instance = new self();
  69951. }
  69952. /**
  69953. * @psalm-param class-string $class
  69954. *
  69955. * @throws AnnotationsAreNotSupportedForInternalClassesException
  69956. * @throws ReflectionException
  69957. */
  69958. public function forClassName(string $class): \PHPUnit\Metadata\Annotation\Parser\DocBlock
  69959. {
  69960. if (array_key_exists($class, $this->classDocBlocks)) {
  69961. return $this->classDocBlocks[$class];
  69962. }
  69963. try {
  69964. $reflection = new ReflectionClass($class);
  69965. // @codeCoverageIgnoreStart
  69966. } catch (\ReflectionException $e) {
  69967. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  69968. }
  69969. // @codeCoverageIgnoreEnd
  69970. return $this->classDocBlocks[$class] = \PHPUnit\Metadata\Annotation\Parser\DocBlock::ofClass($reflection);
  69971. }
  69972. /**
  69973. * @psalm-param class-string $classInHierarchy
  69974. *
  69975. * @throws AnnotationsAreNotSupportedForInternalClassesException
  69976. * @throws ReflectionException
  69977. */
  69978. public function forMethod(string $classInHierarchy, string $method): \PHPUnit\Metadata\Annotation\Parser\DocBlock
  69979. {
  69980. if (isset($this->methodDocBlocks[$classInHierarchy][$method])) {
  69981. return $this->methodDocBlocks[$classInHierarchy][$method];
  69982. }
  69983. try {
  69984. $reflection = new ReflectionMethod($classInHierarchy, $method);
  69985. // @codeCoverageIgnoreStart
  69986. } catch (\ReflectionException $e) {
  69987. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  69988. }
  69989. // @codeCoverageIgnoreEnd
  69990. return $this->methodDocBlocks[$classInHierarchy][$method] = \PHPUnit\Metadata\Annotation\Parser\DocBlock::ofMethod($reflection);
  69991. }
  69992. }
  69993. <?php
  69994. declare (strict_types=1);
  69995. /*
  69996. * This file is part of PHPUnit.
  69997. *
  69998. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  69999. *
  70000. * For the full copyright and license information, please view the LICENSE
  70001. * file that was distributed with this source code.
  70002. */
  70003. namespace PHPUnit\Metadata\Parser;
  70004. use function array_merge;
  70005. use function assert;
  70006. use function class_exists;
  70007. use function count;
  70008. use function explode;
  70009. use function method_exists;
  70010. use function preg_replace;
  70011. use function rtrim;
  70012. use function sprintf;
  70013. use function str_contains;
  70014. use function str_starts_with;
  70015. use function strlen;
  70016. use function substr;
  70017. use function trim;
  70018. use PHPUnit\Event\Facade as EventFacade;
  70019. use PHPUnit\Metadata\Annotation\Parser\Registry as AnnotationRegistry;
  70020. use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
  70021. use PHPUnit\Metadata\InvalidVersionRequirementException;
  70022. use PHPUnit\Metadata\Metadata;
  70023. use PHPUnit\Metadata\MetadataCollection;
  70024. use PHPUnit\Metadata\ReflectionException;
  70025. use PHPUnit\Metadata\Version\ComparisonRequirement;
  70026. use PHPUnit\Metadata\Version\ConstraintRequirement;
  70027. use PHPUnit\Util\InvalidVersionOperatorException;
  70028. use PHPUnit\Util\VersionComparisonOperator;
  70029. /**
  70030. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70031. *
  70032. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70033. */
  70034. final class AnnotationParser implements \PHPUnit\Metadata\Parser\Parser
  70035. {
  70036. /**
  70037. * @psalm-param class-string $className
  70038. *
  70039. * @throws AnnotationsAreNotSupportedForInternalClassesException
  70040. * @throws InvalidVersionOperatorException
  70041. * @throws ReflectionException
  70042. */
  70043. public function forClass(string $className): MetadataCollection
  70044. {
  70045. assert(class_exists($className));
  70046. $result = [];
  70047. foreach (AnnotationRegistry::getInstance()->forClassName($className)->symbolAnnotations() as $annotation => $values) {
  70048. switch ($annotation) {
  70049. case 'backupGlobals':
  70050. $result[] = Metadata::backupGlobalsOnClass($this->stringToBool($values[0]));
  70051. break;
  70052. case 'backupStaticAttributes':
  70053. case 'backupStaticProperties':
  70054. $result[] = Metadata::backupStaticPropertiesOnClass($this->stringToBool($values[0]));
  70055. break;
  70056. case 'covers':
  70057. foreach ($values as $value) {
  70058. $value = $this->cleanUpCoversOrUsesTarget($value);
  70059. $result[] = Metadata::coversOnClass($value);
  70060. }
  70061. break;
  70062. case 'coversDefaultClass':
  70063. foreach ($values as $value) {
  70064. $result[] = Metadata::coversDefaultClass($value);
  70065. }
  70066. break;
  70067. case 'coversNothing':
  70068. $result[] = Metadata::coversNothingOnClass();
  70069. break;
  70070. case 'doesNotPerformAssertions':
  70071. $result[] = Metadata::doesNotPerformAssertionsOnClass();
  70072. break;
  70073. case 'group':
  70074. case 'ticket':
  70075. foreach ($values as $value) {
  70076. $result[] = Metadata::groupOnClass($value);
  70077. }
  70078. break;
  70079. case 'large':
  70080. $result[] = Metadata::groupOnClass('large');
  70081. break;
  70082. case 'medium':
  70083. $result[] = Metadata::groupOnClass('medium');
  70084. break;
  70085. case 'preserveGlobalState':
  70086. $result[] = Metadata::preserveGlobalStateOnClass($this->stringToBool($values[0]));
  70087. break;
  70088. case 'runClassInSeparateProcess':
  70089. $result[] = Metadata::runClassInSeparateProcess();
  70090. break;
  70091. case 'runTestsInSeparateProcesses':
  70092. $result[] = Metadata::runTestsInSeparateProcesses();
  70093. break;
  70094. case 'small':
  70095. $result[] = Metadata::groupOnClass('small');
  70096. break;
  70097. case 'testdox':
  70098. $result[] = Metadata::testDoxOnClass($values[0]);
  70099. break;
  70100. case 'uses':
  70101. foreach ($values as $value) {
  70102. $value = $this->cleanUpCoversOrUsesTarget($value);
  70103. $result[] = Metadata::usesOnClass($value);
  70104. }
  70105. break;
  70106. case 'usesDefaultClass':
  70107. foreach ($values as $value) {
  70108. $result[] = Metadata::usesDefaultClass($value);
  70109. }
  70110. break;
  70111. }
  70112. }
  70113. try {
  70114. $result = array_merge($result, $this->parseRequirements(AnnotationRegistry::getInstance()->forClassName($className)->requirements(), 'class'));
  70115. } catch (InvalidVersionRequirementException $e) {
  70116. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Class %s is annotated using an invalid version requirement: %s', $className, $e->getMessage()));
  70117. }
  70118. return MetadataCollection::fromArray($result);
  70119. }
  70120. /**
  70121. * @psalm-param class-string $className
  70122. * @psalm-param non-empty-string $methodName
  70123. *
  70124. * @throws AnnotationsAreNotSupportedForInternalClassesException
  70125. * @throws InvalidVersionOperatorException
  70126. * @throws ReflectionException
  70127. */
  70128. public function forMethod(string $className, string $methodName): MetadataCollection
  70129. {
  70130. assert(class_exists($className));
  70131. assert(method_exists($className, $methodName));
  70132. $result = [];
  70133. foreach (AnnotationRegistry::getInstance()->forMethod($className, $methodName)->symbolAnnotations() as $annotation => $values) {
  70134. switch ($annotation) {
  70135. case 'after':
  70136. $result[] = Metadata::after();
  70137. break;
  70138. case 'afterClass':
  70139. $result[] = Metadata::afterClass();
  70140. break;
  70141. case 'backupGlobals':
  70142. $result[] = Metadata::backupGlobalsOnMethod($this->stringToBool($values[0]));
  70143. break;
  70144. case 'backupStaticAttributes':
  70145. case 'backupStaticProperties':
  70146. $result[] = Metadata::backupStaticPropertiesOnMethod($this->stringToBool($values[0]));
  70147. break;
  70148. case 'before':
  70149. $result[] = Metadata::before();
  70150. break;
  70151. case 'beforeClass':
  70152. $result[] = Metadata::beforeClass();
  70153. break;
  70154. case 'covers':
  70155. foreach ($values as $value) {
  70156. $value = $this->cleanUpCoversOrUsesTarget($value);
  70157. $result[] = Metadata::coversOnMethod($value);
  70158. }
  70159. break;
  70160. case 'coversNothing':
  70161. $result[] = Metadata::coversNothingOnMethod();
  70162. break;
  70163. case 'dataProvider':
  70164. foreach ($values as $value) {
  70165. $value = rtrim($value, " ()\n\r\t\v\x00");
  70166. if (str_contains($value, '::')) {
  70167. $result[] = Metadata::dataProvider(...explode('::', $value));
  70168. continue;
  70169. }
  70170. $result[] = Metadata::dataProvider($className, $value);
  70171. }
  70172. break;
  70173. case 'depends':
  70174. foreach ($values as $value) {
  70175. $deepClone = \false;
  70176. $shallowClone = \false;
  70177. if (str_starts_with($value, 'clone ')) {
  70178. $deepClone = \true;
  70179. $value = substr($value, strlen('clone '));
  70180. } elseif (str_starts_with($value, '!clone ')) {
  70181. $value = substr($value, strlen('!clone '));
  70182. } elseif (str_starts_with($value, 'shallowClone ')) {
  70183. $shallowClone = \true;
  70184. $value = substr($value, strlen('shallowClone '));
  70185. } elseif (str_starts_with($value, '!shallowClone ')) {
  70186. $value = substr($value, strlen('!shallowClone '));
  70187. }
  70188. if (str_contains($value, '::')) {
  70189. [$_className, $_methodName] = explode('::', $value);
  70190. assert($_className !== '');
  70191. assert($_methodName !== '');
  70192. if ($_methodName === 'class') {
  70193. $result[] = Metadata::dependsOnClass($_className, $deepClone, $shallowClone);
  70194. continue;
  70195. }
  70196. $result[] = Metadata::dependsOnMethod($_className, $_methodName, $deepClone, $shallowClone);
  70197. continue;
  70198. }
  70199. $result[] = Metadata::dependsOnMethod($className, $value, $deepClone, $shallowClone);
  70200. }
  70201. break;
  70202. case 'doesNotPerformAssertions':
  70203. $result[] = Metadata::doesNotPerformAssertionsOnMethod();
  70204. break;
  70205. case 'excludeGlobalVariableFromBackup':
  70206. foreach ($values as $value) {
  70207. $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($value);
  70208. }
  70209. break;
  70210. case 'excludeStaticPropertyFromBackup':
  70211. foreach ($values as $value) {
  70212. $tmp = explode(' ', $value);
  70213. if (count($tmp) !== 2) {
  70214. continue;
  70215. }
  70216. $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod(trim($tmp[0]), trim($tmp[1]));
  70217. }
  70218. break;
  70219. case 'group':
  70220. case 'ticket':
  70221. foreach ($values as $value) {
  70222. $result[] = Metadata::groupOnMethod($value);
  70223. }
  70224. break;
  70225. case 'large':
  70226. $result[] = Metadata::groupOnMethod('large');
  70227. break;
  70228. case 'medium':
  70229. $result[] = Metadata::groupOnMethod('medium');
  70230. break;
  70231. case 'postCondition':
  70232. $result[] = Metadata::postCondition();
  70233. break;
  70234. case 'preCondition':
  70235. $result[] = Metadata::preCondition();
  70236. break;
  70237. case 'preserveGlobalState':
  70238. $result[] = Metadata::preserveGlobalStateOnMethod($this->stringToBool($values[0]));
  70239. break;
  70240. case 'runInSeparateProcess':
  70241. $result[] = Metadata::runInSeparateProcess();
  70242. break;
  70243. case 'small':
  70244. $result[] = Metadata::groupOnMethod('small');
  70245. break;
  70246. case 'test':
  70247. $result[] = Metadata::test();
  70248. break;
  70249. case 'testdox':
  70250. $result[] = Metadata::testDoxOnMethod($values[0]);
  70251. break;
  70252. case 'uses':
  70253. foreach ($values as $value) {
  70254. $value = $this->cleanUpCoversOrUsesTarget($value);
  70255. $result[] = Metadata::usesOnMethod($value);
  70256. }
  70257. break;
  70258. }
  70259. }
  70260. if (method_exists($className, $methodName)) {
  70261. try {
  70262. $result = array_merge($result, $this->parseRequirements(AnnotationRegistry::getInstance()->forMethod($className, $methodName)->requirements(), 'method'));
  70263. } catch (InvalidVersionRequirementException $e) {
  70264. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Method %s::%s is annotated using an invalid version requirement: %s', $className, $methodName, $e->getMessage()));
  70265. }
  70266. }
  70267. return MetadataCollection::fromArray($result);
  70268. }
  70269. /**
  70270. * @psalm-param class-string $className
  70271. * @psalm-param non-empty-string $methodName
  70272. *
  70273. * @throws AnnotationsAreNotSupportedForInternalClassesException
  70274. * @throws InvalidVersionOperatorException
  70275. * @throws ReflectionException
  70276. */
  70277. public function forClassAndMethod(string $className, string $methodName): MetadataCollection
  70278. {
  70279. return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
  70280. }
  70281. private function stringToBool(string $value): bool
  70282. {
  70283. if ($value === 'enabled') {
  70284. return \true;
  70285. }
  70286. return \false;
  70287. }
  70288. private function cleanUpCoversOrUsesTarget(string $value): string
  70289. {
  70290. $value = preg_replace('/[\s()]+$/', '', $value);
  70291. return explode(' ', $value, 2)[0];
  70292. }
  70293. /**
  70294. * @psalm-return list<Metadata>
  70295. *
  70296. * @throws InvalidVersionOperatorException
  70297. */
  70298. private function parseRequirements(array $requirements, string $level): array
  70299. {
  70300. $result = [];
  70301. if (!empty($requirements['PHP'])) {
  70302. $versionRequirement = new ComparisonRequirement($requirements['PHP']['version'], new VersionComparisonOperator(empty($requirements['PHP']['operator']) ? '>=' : $requirements['PHP']['operator']));
  70303. if ($level === 'class') {
  70304. $result[] = Metadata::requiresPhpOnClass($versionRequirement);
  70305. } else {
  70306. $result[] = Metadata::requiresPhpOnMethod($versionRequirement);
  70307. }
  70308. } elseif (!empty($requirements['PHP_constraint'])) {
  70309. $versionRequirement = new ConstraintRequirement($requirements['PHP_constraint']['constraint']);
  70310. if ($level === 'class') {
  70311. $result[] = Metadata::requiresPhpOnClass($versionRequirement);
  70312. } else {
  70313. $result[] = Metadata::requiresPhpOnMethod($versionRequirement);
  70314. }
  70315. }
  70316. if (!empty($requirements['extensions'])) {
  70317. foreach ($requirements['extensions'] as $extension) {
  70318. if (isset($requirements['extension_versions'][$extension])) {
  70319. continue;
  70320. }
  70321. if ($level === 'class') {
  70322. $result[] = Metadata::requiresPhpExtensionOnClass($extension, null);
  70323. } else {
  70324. $result[] = Metadata::requiresPhpExtensionOnMethod($extension, null);
  70325. }
  70326. }
  70327. }
  70328. if (!empty($requirements['extension_versions'])) {
  70329. foreach ($requirements['extension_versions'] as $extension => $version) {
  70330. $versionRequirement = new ComparisonRequirement($version['version'], new VersionComparisonOperator(empty($version['operator']) ? '>=' : $version['operator']));
  70331. if ($level === 'class') {
  70332. $result[] = Metadata::requiresPhpExtensionOnClass($extension, $versionRequirement);
  70333. } else {
  70334. $result[] = Metadata::requiresPhpExtensionOnMethod($extension, $versionRequirement);
  70335. }
  70336. }
  70337. }
  70338. if (!empty($requirements['PHPUnit'])) {
  70339. $versionRequirement = new ComparisonRequirement($requirements['PHPUnit']['version'], new VersionComparisonOperator(empty($requirements['PHPUnit']['operator']) ? '>=' : $requirements['PHPUnit']['operator']));
  70340. if ($level === 'class') {
  70341. $result[] = Metadata::requiresPhpunitOnClass($versionRequirement);
  70342. } else {
  70343. $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement);
  70344. }
  70345. } elseif (!empty($requirements['PHPUnit_constraint'])) {
  70346. $versionRequirement = new ConstraintRequirement($requirements['PHPUnit_constraint']['constraint']);
  70347. if ($level === 'class') {
  70348. $result[] = Metadata::requiresPhpunitOnClass($versionRequirement);
  70349. } else {
  70350. $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement);
  70351. }
  70352. }
  70353. if (!empty($requirements['OSFAMILY'])) {
  70354. if ($level === 'class') {
  70355. $result[] = Metadata::requiresOperatingSystemFamilyOnClass($requirements['OSFAMILY']);
  70356. } else {
  70357. $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($requirements['OSFAMILY']);
  70358. }
  70359. }
  70360. if (!empty($requirements['OS'])) {
  70361. if ($level === 'class') {
  70362. $result[] = Metadata::requiresOperatingSystemOnClass($requirements['OS']);
  70363. } else {
  70364. $result[] = Metadata::requiresOperatingSystemOnMethod($requirements['OS']);
  70365. }
  70366. }
  70367. if (!empty($requirements['functions'])) {
  70368. foreach ($requirements['functions'] as $function) {
  70369. $pieces = explode('::', $function);
  70370. if (count($pieces) === 2) {
  70371. if ($level === 'class') {
  70372. $result[] = Metadata::requiresMethodOnClass($pieces[0], $pieces[1]);
  70373. } else {
  70374. $result[] = Metadata::requiresMethodOnMethod($pieces[0], $pieces[1]);
  70375. }
  70376. } elseif ($level === 'class') {
  70377. $result[] = Metadata::requiresFunctionOnClass($function);
  70378. } else {
  70379. $result[] = Metadata::requiresFunctionOnMethod($function);
  70380. }
  70381. }
  70382. }
  70383. if (!empty($requirements['setting'])) {
  70384. foreach ($requirements['setting'] as $setting => $value) {
  70385. if ($level === 'class') {
  70386. $result[] = Metadata::requiresSettingOnClass($setting, $value);
  70387. } else {
  70388. $result[] = Metadata::requiresSettingOnMethod($setting, $value);
  70389. }
  70390. }
  70391. }
  70392. return $result;
  70393. }
  70394. }
  70395. <?php
  70396. declare (strict_types=1);
  70397. /*
  70398. * This file is part of PHPUnit.
  70399. *
  70400. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  70401. *
  70402. * For the full copyright and license information, please view the LICENSE
  70403. * file that was distributed with this source code.
  70404. */
  70405. namespace PHPUnit\Metadata\Parser;
  70406. use const JSON_THROW_ON_ERROR;
  70407. use function assert;
  70408. use function class_exists;
  70409. use function json_decode;
  70410. use function method_exists;
  70411. use function str_starts_with;
  70412. use PHPUnit\Framework\Attributes\After;
  70413. use PHPUnit\Framework\Attributes\AfterClass;
  70414. use PHPUnit\Framework\Attributes\BackupGlobals;
  70415. use PHPUnit\Framework\Attributes\BackupStaticProperties;
  70416. use PHPUnit\Framework\Attributes\Before;
  70417. use PHPUnit\Framework\Attributes\BeforeClass;
  70418. use PHPUnit\Framework\Attributes\CoversClass;
  70419. use PHPUnit\Framework\Attributes\CoversFunction;
  70420. use PHPUnit\Framework\Attributes\CoversNothing;
  70421. use PHPUnit\Framework\Attributes\DataProvider;
  70422. use PHPUnit\Framework\Attributes\DataProviderExternal;
  70423. use PHPUnit\Framework\Attributes\Depends;
  70424. use PHPUnit\Framework\Attributes\DependsExternal;
  70425. use PHPUnit\Framework\Attributes\DependsExternalUsingDeepClone;
  70426. use PHPUnit\Framework\Attributes\DependsExternalUsingShallowClone;
  70427. use PHPUnit\Framework\Attributes\DependsOnClass;
  70428. use PHPUnit\Framework\Attributes\DependsOnClassUsingDeepClone;
  70429. use PHPUnit\Framework\Attributes\DependsOnClassUsingShallowClone;
  70430. use PHPUnit\Framework\Attributes\DependsUsingDeepClone;
  70431. use PHPUnit\Framework\Attributes\DependsUsingShallowClone;
  70432. use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
  70433. use PHPUnit\Framework\Attributes\ExcludeGlobalVariableFromBackup;
  70434. use PHPUnit\Framework\Attributes\ExcludeStaticPropertyFromBackup;
  70435. use PHPUnit\Framework\Attributes\Group;
  70436. use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage;
  70437. use PHPUnit\Framework\Attributes\IgnoreDeprecations;
  70438. use PHPUnit\Framework\Attributes\IgnoreFunctionForCodeCoverage;
  70439. use PHPUnit\Framework\Attributes\IgnoreMethodForCodeCoverage;
  70440. use PHPUnit\Framework\Attributes\Large;
  70441. use PHPUnit\Framework\Attributes\Medium;
  70442. use PHPUnit\Framework\Attributes\PostCondition;
  70443. use PHPUnit\Framework\Attributes\PreCondition;
  70444. use PHPUnit\Framework\Attributes\PreserveGlobalState;
  70445. use PHPUnit\Framework\Attributes\RequiresFunction;
  70446. use PHPUnit\Framework\Attributes\RequiresMethod;
  70447. use PHPUnit\Framework\Attributes\RequiresOperatingSystem;
  70448. use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily;
  70449. use PHPUnit\Framework\Attributes\RequiresPhp;
  70450. use PHPUnit\Framework\Attributes\RequiresPhpExtension;
  70451. use PHPUnit\Framework\Attributes\RequiresPhpunit;
  70452. use PHPUnit\Framework\Attributes\RequiresSetting;
  70453. use PHPUnit\Framework\Attributes\RunClassInSeparateProcess;
  70454. use PHPUnit\Framework\Attributes\RunInSeparateProcess;
  70455. use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
  70456. use PHPUnit\Framework\Attributes\Small;
  70457. use PHPUnit\Framework\Attributes\Test;
  70458. use PHPUnit\Framework\Attributes\TestDox;
  70459. use PHPUnit\Framework\Attributes\TestWith;
  70460. use PHPUnit\Framework\Attributes\TestWithJson;
  70461. use PHPUnit\Framework\Attributes\Ticket;
  70462. use PHPUnit\Framework\Attributes\UsesClass;
  70463. use PHPUnit\Framework\Attributes\UsesFunction;
  70464. use PHPUnit\Framework\Attributes\WithoutErrorHandler;
  70465. use PHPUnit\Metadata\Metadata;
  70466. use PHPUnit\Metadata\MetadataCollection;
  70467. use PHPUnit\Metadata\Version\ConstraintRequirement;
  70468. use ReflectionClass;
  70469. use ReflectionMethod;
  70470. /**
  70471. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70472. *
  70473. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70474. */
  70475. final class AttributeParser implements \PHPUnit\Metadata\Parser\Parser
  70476. {
  70477. /**
  70478. * @psalm-param class-string $className
  70479. */
  70480. public function forClass(string $className): MetadataCollection
  70481. {
  70482. assert(class_exists($className));
  70483. $result = [];
  70484. foreach ((new ReflectionClass($className))->getAttributes() as $attribute) {
  70485. if (!str_starts_with($attribute->getName(), 'PHPUnit\Framework\Attributes\\')) {
  70486. continue;
  70487. }
  70488. if (!class_exists($attribute->getName())) {
  70489. continue;
  70490. }
  70491. $attributeInstance = $attribute->newInstance();
  70492. switch ($attribute->getName()) {
  70493. case BackupGlobals::class:
  70494. assert($attributeInstance instanceof BackupGlobals);
  70495. $result[] = Metadata::backupGlobalsOnClass($attributeInstance->enabled());
  70496. break;
  70497. case BackupStaticProperties::class:
  70498. assert($attributeInstance instanceof BackupStaticProperties);
  70499. $result[] = Metadata::backupStaticPropertiesOnClass($attributeInstance->enabled());
  70500. break;
  70501. case CoversClass::class:
  70502. assert($attributeInstance instanceof CoversClass);
  70503. $result[] = Metadata::coversClass($attributeInstance->className());
  70504. break;
  70505. case CoversFunction::class:
  70506. assert($attributeInstance instanceof CoversFunction);
  70507. $result[] = Metadata::coversFunction($attributeInstance->functionName());
  70508. break;
  70509. case CoversNothing::class:
  70510. $result[] = Metadata::coversNothingOnClass();
  70511. break;
  70512. case DoesNotPerformAssertions::class:
  70513. $result[] = Metadata::doesNotPerformAssertionsOnClass();
  70514. break;
  70515. case ExcludeGlobalVariableFromBackup::class:
  70516. assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup);
  70517. $result[] = Metadata::excludeGlobalVariableFromBackupOnClass($attributeInstance->globalVariableName());
  70518. break;
  70519. case ExcludeStaticPropertyFromBackup::class:
  70520. assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup);
  70521. $result[] = Metadata::excludeStaticPropertyFromBackupOnClass($attributeInstance->className(), $attributeInstance->propertyName());
  70522. break;
  70523. case Group::class:
  70524. assert($attributeInstance instanceof Group);
  70525. $result[] = Metadata::groupOnClass($attributeInstance->name());
  70526. break;
  70527. case Large::class:
  70528. $result[] = Metadata::groupOnClass('large');
  70529. break;
  70530. case Medium::class:
  70531. $result[] = Metadata::groupOnClass('medium');
  70532. break;
  70533. case IgnoreClassForCodeCoverage::class:
  70534. assert($attributeInstance instanceof IgnoreClassForCodeCoverage);
  70535. $result[] = Metadata::ignoreClassForCodeCoverage($attributeInstance->className());
  70536. break;
  70537. case IgnoreDeprecations::class:
  70538. assert($attributeInstance instanceof IgnoreDeprecations);
  70539. $result[] = Metadata::ignoreDeprecationsOnClass();
  70540. break;
  70541. case IgnoreMethodForCodeCoverage::class:
  70542. assert($attributeInstance instanceof IgnoreMethodForCodeCoverage);
  70543. $result[] = Metadata::ignoreMethodForCodeCoverage($attributeInstance->className(), $attributeInstance->methodName());
  70544. break;
  70545. case IgnoreFunctionForCodeCoverage::class:
  70546. assert($attributeInstance instanceof IgnoreFunctionForCodeCoverage);
  70547. $result[] = Metadata::ignoreFunctionForCodeCoverage($attributeInstance->functionName());
  70548. break;
  70549. case PreserveGlobalState::class:
  70550. assert($attributeInstance instanceof PreserveGlobalState);
  70551. $result[] = Metadata::preserveGlobalStateOnClass($attributeInstance->enabled());
  70552. break;
  70553. case RequiresMethod::class:
  70554. assert($attributeInstance instanceof RequiresMethod);
  70555. $result[] = Metadata::requiresMethodOnClass($attributeInstance->className(), $attributeInstance->methodName());
  70556. break;
  70557. case RequiresFunction::class:
  70558. assert($attributeInstance instanceof RequiresFunction);
  70559. $result[] = Metadata::requiresFunctionOnClass($attributeInstance->functionName());
  70560. break;
  70561. case RequiresOperatingSystem::class:
  70562. assert($attributeInstance instanceof RequiresOperatingSystem);
  70563. $result[] = Metadata::requiresOperatingSystemOnClass($attributeInstance->regularExpression());
  70564. break;
  70565. case RequiresOperatingSystemFamily::class:
  70566. assert($attributeInstance instanceof RequiresOperatingSystemFamily);
  70567. $result[] = Metadata::requiresOperatingSystemFamilyOnClass($attributeInstance->operatingSystemFamily());
  70568. break;
  70569. case RequiresPhp::class:
  70570. assert($attributeInstance instanceof RequiresPhp);
  70571. $result[] = Metadata::requiresPhpOnClass(ConstraintRequirement::from($attributeInstance->versionRequirement()));
  70572. break;
  70573. case RequiresPhpExtension::class:
  70574. assert($attributeInstance instanceof RequiresPhpExtension);
  70575. $versionConstraint = null;
  70576. $versionRequirement = $attributeInstance->versionRequirement();
  70577. if ($versionRequirement !== null) {
  70578. $versionConstraint = ConstraintRequirement::from($versionRequirement);
  70579. }
  70580. $result[] = Metadata::requiresPhpExtensionOnClass($attributeInstance->extension(), $versionConstraint);
  70581. break;
  70582. case RequiresPhpunit::class:
  70583. assert($attributeInstance instanceof RequiresPhpunit);
  70584. $result[] = Metadata::requiresPhpunitOnClass(ConstraintRequirement::from($attributeInstance->versionRequirement()));
  70585. break;
  70586. case RequiresSetting::class:
  70587. assert($attributeInstance instanceof RequiresSetting);
  70588. $result[] = Metadata::requiresSettingOnClass($attributeInstance->setting(), $attributeInstance->value());
  70589. break;
  70590. case RunClassInSeparateProcess::class:
  70591. $result[] = Metadata::runClassInSeparateProcess();
  70592. break;
  70593. case RunTestsInSeparateProcesses::class:
  70594. $result[] = Metadata::runTestsInSeparateProcesses();
  70595. break;
  70596. case Small::class:
  70597. $result[] = Metadata::groupOnClass('small');
  70598. break;
  70599. case TestDox::class:
  70600. assert($attributeInstance instanceof TestDox);
  70601. $result[] = Metadata::testDoxOnClass($attributeInstance->text());
  70602. break;
  70603. case Ticket::class:
  70604. assert($attributeInstance instanceof Ticket);
  70605. $result[] = Metadata::groupOnClass($attributeInstance->text());
  70606. break;
  70607. case UsesClass::class:
  70608. assert($attributeInstance instanceof UsesClass);
  70609. $result[] = Metadata::usesClass($attributeInstance->className());
  70610. break;
  70611. case UsesFunction::class:
  70612. assert($attributeInstance instanceof UsesFunction);
  70613. $result[] = Metadata::usesFunction($attributeInstance->functionName());
  70614. break;
  70615. }
  70616. }
  70617. return MetadataCollection::fromArray($result);
  70618. }
  70619. /**
  70620. * @psalm-param class-string $className
  70621. * @psalm-param non-empty-string $methodName
  70622. */
  70623. public function forMethod(string $className, string $methodName): MetadataCollection
  70624. {
  70625. assert(class_exists($className));
  70626. assert(method_exists($className, $methodName));
  70627. $result = [];
  70628. foreach ((new ReflectionMethod($className, $methodName))->getAttributes() as $attribute) {
  70629. if (!str_starts_with($attribute->getName(), 'PHPUnit\Framework\Attributes\\')) {
  70630. continue;
  70631. }
  70632. if (!class_exists($attribute->getName())) {
  70633. continue;
  70634. }
  70635. $attributeInstance = $attribute->newInstance();
  70636. switch ($attribute->getName()) {
  70637. case After::class:
  70638. $result[] = Metadata::after();
  70639. break;
  70640. case AfterClass::class:
  70641. $result[] = Metadata::afterClass();
  70642. break;
  70643. case BackupGlobals::class:
  70644. assert($attributeInstance instanceof BackupGlobals);
  70645. $result[] = Metadata::backupGlobalsOnMethod($attributeInstance->enabled());
  70646. break;
  70647. case BackupStaticProperties::class:
  70648. assert($attributeInstance instanceof BackupStaticProperties);
  70649. $result[] = Metadata::backupStaticPropertiesOnMethod($attributeInstance->enabled());
  70650. break;
  70651. case Before::class:
  70652. $result[] = Metadata::before();
  70653. break;
  70654. case BeforeClass::class:
  70655. $result[] = Metadata::beforeClass();
  70656. break;
  70657. case CoversNothing::class:
  70658. $result[] = Metadata::coversNothingOnMethod();
  70659. break;
  70660. case DataProvider::class:
  70661. assert($attributeInstance instanceof DataProvider);
  70662. $result[] = Metadata::dataProvider($className, $attributeInstance->methodName());
  70663. break;
  70664. case DataProviderExternal::class:
  70665. assert($attributeInstance instanceof DataProviderExternal);
  70666. $result[] = Metadata::dataProvider($attributeInstance->className(), $attributeInstance->methodName());
  70667. break;
  70668. case Depends::class:
  70669. assert($attributeInstance instanceof Depends);
  70670. $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \false, \false);
  70671. break;
  70672. case DependsUsingDeepClone::class:
  70673. assert($attributeInstance instanceof DependsUsingDeepClone);
  70674. $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \true, \false);
  70675. break;
  70676. case DependsUsingShallowClone::class:
  70677. assert($attributeInstance instanceof DependsUsingShallowClone);
  70678. $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \false, \true);
  70679. break;
  70680. case DependsExternal::class:
  70681. assert($attributeInstance instanceof DependsExternal);
  70682. $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \false, \false);
  70683. break;
  70684. case DependsExternalUsingDeepClone::class:
  70685. assert($attributeInstance instanceof DependsExternalUsingDeepClone);
  70686. $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \true, \false);
  70687. break;
  70688. case DependsExternalUsingShallowClone::class:
  70689. assert($attributeInstance instanceof DependsExternalUsingShallowClone);
  70690. $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \false, \true);
  70691. break;
  70692. case DependsOnClass::class:
  70693. assert($attributeInstance instanceof DependsOnClass);
  70694. $result[] = Metadata::dependsOnClass($attributeInstance->className(), \false, \false);
  70695. break;
  70696. case DependsOnClassUsingDeepClone::class:
  70697. assert($attributeInstance instanceof DependsOnClassUsingDeepClone);
  70698. $result[] = Metadata::dependsOnClass($attributeInstance->className(), \true, \false);
  70699. break;
  70700. case DependsOnClassUsingShallowClone::class:
  70701. assert($attributeInstance instanceof DependsOnClassUsingShallowClone);
  70702. $result[] = Metadata::dependsOnClass($attributeInstance->className(), \false, \true);
  70703. break;
  70704. case DoesNotPerformAssertions::class:
  70705. assert($attributeInstance instanceof DoesNotPerformAssertions);
  70706. $result[] = Metadata::doesNotPerformAssertionsOnMethod();
  70707. break;
  70708. case ExcludeGlobalVariableFromBackup::class:
  70709. assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup);
  70710. $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($attributeInstance->globalVariableName());
  70711. break;
  70712. case ExcludeStaticPropertyFromBackup::class:
  70713. assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup);
  70714. $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod($attributeInstance->className(), $attributeInstance->propertyName());
  70715. break;
  70716. case Group::class:
  70717. assert($attributeInstance instanceof Group);
  70718. $result[] = Metadata::groupOnMethod($attributeInstance->name());
  70719. break;
  70720. case IgnoreDeprecations::class:
  70721. assert($attributeInstance instanceof IgnoreDeprecations);
  70722. $result[] = Metadata::ignoreDeprecationsOnMethod();
  70723. break;
  70724. case PostCondition::class:
  70725. $result[] = Metadata::postCondition();
  70726. break;
  70727. case PreCondition::class:
  70728. $result[] = Metadata::preCondition();
  70729. break;
  70730. case PreserveGlobalState::class:
  70731. assert($attributeInstance instanceof PreserveGlobalState);
  70732. $result[] = Metadata::preserveGlobalStateOnMethod($attributeInstance->enabled());
  70733. break;
  70734. case RequiresMethod::class:
  70735. assert($attributeInstance instanceof RequiresMethod);
  70736. $result[] = Metadata::requiresMethodOnMethod($attributeInstance->className(), $attributeInstance->methodName());
  70737. break;
  70738. case RequiresFunction::class:
  70739. assert($attributeInstance instanceof RequiresFunction);
  70740. $result[] = Metadata::requiresFunctionOnMethod($attributeInstance->functionName());
  70741. break;
  70742. case RequiresOperatingSystem::class:
  70743. assert($attributeInstance instanceof RequiresOperatingSystem);
  70744. $result[] = Metadata::requiresOperatingSystemOnMethod($attributeInstance->regularExpression());
  70745. break;
  70746. case RequiresOperatingSystemFamily::class:
  70747. assert($attributeInstance instanceof RequiresOperatingSystemFamily);
  70748. $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($attributeInstance->operatingSystemFamily());
  70749. break;
  70750. case RequiresPhp::class:
  70751. assert($attributeInstance instanceof RequiresPhp);
  70752. $result[] = Metadata::requiresPhpOnMethod(ConstraintRequirement::from($attributeInstance->versionRequirement()));
  70753. break;
  70754. case RequiresPhpExtension::class:
  70755. assert($attributeInstance instanceof RequiresPhpExtension);
  70756. $versionConstraint = null;
  70757. $versionRequirement = $attributeInstance->versionRequirement();
  70758. if ($versionRequirement !== null) {
  70759. $versionConstraint = ConstraintRequirement::from($versionRequirement);
  70760. }
  70761. $result[] = Metadata::requiresPhpExtensionOnMethod($attributeInstance->extension(), $versionConstraint);
  70762. break;
  70763. case RequiresPhpunit::class:
  70764. assert($attributeInstance instanceof RequiresPhpunit);
  70765. $result[] = Metadata::requiresPhpunitOnMethod(ConstraintRequirement::from($attributeInstance->versionRequirement()));
  70766. break;
  70767. case RequiresSetting::class:
  70768. assert($attributeInstance instanceof RequiresSetting);
  70769. $result[] = Metadata::requiresSettingOnMethod($attributeInstance->setting(), $attributeInstance->value());
  70770. break;
  70771. case RunInSeparateProcess::class:
  70772. $result[] = Metadata::runInSeparateProcess();
  70773. break;
  70774. case Test::class:
  70775. $result[] = Metadata::test();
  70776. break;
  70777. case TestDox::class:
  70778. assert($attributeInstance instanceof TestDox);
  70779. $result[] = Metadata::testDoxOnMethod($attributeInstance->text());
  70780. break;
  70781. case TestWith::class:
  70782. assert($attributeInstance instanceof TestWith);
  70783. $result[] = Metadata::testWith($attributeInstance->data());
  70784. break;
  70785. case TestWithJson::class:
  70786. assert($attributeInstance instanceof TestWithJson);
  70787. $result[] = Metadata::testWith(json_decode($attributeInstance->json(), \true, 512, JSON_THROW_ON_ERROR));
  70788. break;
  70789. case Ticket::class:
  70790. assert($attributeInstance instanceof Ticket);
  70791. $result[] = Metadata::groupOnMethod($attributeInstance->text());
  70792. break;
  70793. case WithoutErrorHandler::class:
  70794. assert($attributeInstance instanceof WithoutErrorHandler);
  70795. $result[] = Metadata::withoutErrorHandler();
  70796. break;
  70797. }
  70798. }
  70799. return MetadataCollection::fromArray($result);
  70800. }
  70801. /**
  70802. * @psalm-param class-string $className
  70803. * @psalm-param non-empty-string $methodName
  70804. */
  70805. public function forClassAndMethod(string $className, string $methodName): MetadataCollection
  70806. {
  70807. return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
  70808. }
  70809. }
  70810. <?php
  70811. declare (strict_types=1);
  70812. /*
  70813. * This file is part of PHPUnit.
  70814. *
  70815. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  70816. *
  70817. * For the full copyright and license information, please view the LICENSE
  70818. * file that was distributed with this source code.
  70819. */
  70820. namespace PHPUnit\Metadata\Parser;
  70821. use function assert;
  70822. use function class_exists;
  70823. use function method_exists;
  70824. use PHPUnit\Metadata\MetadataCollection;
  70825. /**
  70826. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70827. *
  70828. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70829. */
  70830. final class CachingParser implements \PHPUnit\Metadata\Parser\Parser
  70831. {
  70832. private readonly \PHPUnit\Metadata\Parser\Parser $reader;
  70833. private array $classCache = [];
  70834. private array $methodCache = [];
  70835. private array $classAndMethodCache = [];
  70836. public function __construct(\PHPUnit\Metadata\Parser\Parser $reader)
  70837. {
  70838. $this->reader = $reader;
  70839. }
  70840. /**
  70841. * @psalm-param class-string $className
  70842. */
  70843. public function forClass(string $className): MetadataCollection
  70844. {
  70845. assert(class_exists($className));
  70846. if (isset($this->classCache[$className])) {
  70847. return $this->classCache[$className];
  70848. }
  70849. $this->classCache[$className] = $this->reader->forClass($className);
  70850. return $this->classCache[$className];
  70851. }
  70852. /**
  70853. * @psalm-param class-string $className
  70854. * @psalm-param non-empty-string $methodName
  70855. */
  70856. public function forMethod(string $className, string $methodName): MetadataCollection
  70857. {
  70858. assert(class_exists($className));
  70859. assert(method_exists($className, $methodName));
  70860. $key = $className . '::' . $methodName;
  70861. if (isset($this->methodCache[$key])) {
  70862. return $this->methodCache[$key];
  70863. }
  70864. $this->methodCache[$key] = $this->reader->forMethod($className, $methodName);
  70865. return $this->methodCache[$key];
  70866. }
  70867. /**
  70868. * @psalm-param class-string $className
  70869. * @psalm-param non-empty-string $methodName
  70870. */
  70871. public function forClassAndMethod(string $className, string $methodName): MetadataCollection
  70872. {
  70873. $key = $className . '::' . $methodName;
  70874. if (isset($this->classAndMethodCache[$key])) {
  70875. return $this->classAndMethodCache[$key];
  70876. }
  70877. $this->classAndMethodCache[$key] = $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
  70878. return $this->classAndMethodCache[$key];
  70879. }
  70880. }
  70881. <?php
  70882. declare (strict_types=1);
  70883. /*
  70884. * This file is part of PHPUnit.
  70885. *
  70886. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  70887. *
  70888. * For the full copyright and license information, please view the LICENSE
  70889. * file that was distributed with this source code.
  70890. */
  70891. namespace PHPUnit\Metadata\Parser;
  70892. use PHPUnit\Metadata\MetadataCollection;
  70893. /**
  70894. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70895. *
  70896. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70897. */
  70898. interface Parser
  70899. {
  70900. /**
  70901. * @psalm-param class-string $className
  70902. */
  70903. public function forClass(string $className): MetadataCollection;
  70904. /**
  70905. * @psalm-param class-string $className
  70906. * @psalm-param non-empty-string $methodName
  70907. */
  70908. public function forMethod(string $className, string $methodName): MetadataCollection;
  70909. /**
  70910. * @psalm-param class-string $className
  70911. * @psalm-param non-empty-string $methodName
  70912. */
  70913. public function forClassAndMethod(string $className, string $methodName): MetadataCollection;
  70914. }
  70915. <?php
  70916. declare (strict_types=1);
  70917. /*
  70918. * This file is part of PHPUnit.
  70919. *
  70920. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  70921. *
  70922. * For the full copyright and license information, please view the LICENSE
  70923. * file that was distributed with this source code.
  70924. */
  70925. namespace PHPUnit\Metadata\Parser;
  70926. use function assert;
  70927. use function class_exists;
  70928. use function method_exists;
  70929. use PHPUnit\Metadata\MetadataCollection;
  70930. /**
  70931. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70932. *
  70933. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70934. */
  70935. final class ParserChain implements \PHPUnit\Metadata\Parser\Parser
  70936. {
  70937. private readonly \PHPUnit\Metadata\Parser\Parser $attributeReader;
  70938. private readonly \PHPUnit\Metadata\Parser\Parser $annotationReader;
  70939. public function __construct(\PHPUnit\Metadata\Parser\Parser $attributeReader, \PHPUnit\Metadata\Parser\Parser $annotationReader)
  70940. {
  70941. $this->attributeReader = $attributeReader;
  70942. $this->annotationReader = $annotationReader;
  70943. }
  70944. /**
  70945. * @psalm-param class-string $className
  70946. */
  70947. public function forClass(string $className): MetadataCollection
  70948. {
  70949. assert(class_exists($className));
  70950. $metadata = $this->attributeReader->forClass($className);
  70951. if (!$metadata->isEmpty()) {
  70952. return $metadata;
  70953. }
  70954. return $this->annotationReader->forClass($className);
  70955. }
  70956. /**
  70957. * @psalm-param class-string $className
  70958. * @psalm-param non-empty-string $methodName
  70959. */
  70960. public function forMethod(string $className, string $methodName): MetadataCollection
  70961. {
  70962. assert(class_exists($className));
  70963. assert(method_exists($className, $methodName));
  70964. $metadata = $this->attributeReader->forMethod($className, $methodName);
  70965. if (!$metadata->isEmpty()) {
  70966. return $metadata;
  70967. }
  70968. return $this->annotationReader->forMethod($className, $methodName);
  70969. }
  70970. /**
  70971. * @psalm-param class-string $className
  70972. * @psalm-param non-empty-string $methodName
  70973. */
  70974. public function forClassAndMethod(string $className, string $methodName): MetadataCollection
  70975. {
  70976. return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
  70977. }
  70978. }
  70979. <?php
  70980. declare (strict_types=1);
  70981. /*
  70982. * This file is part of PHPUnit.
  70983. *
  70984. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  70985. *
  70986. * For the full copyright and license information, please view the LICENSE
  70987. * file that was distributed with this source code.
  70988. */
  70989. namespace PHPUnit\Metadata\Parser;
  70990. /**
  70991. * Attribute and annotation information is static within a single PHP process.
  70992. * It is therefore okay to use a Singleton registry here.
  70993. *
  70994. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  70995. *
  70996. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  70997. */
  70998. final class Registry
  70999. {
  71000. private static ?\PHPUnit\Metadata\Parser\Parser $instance = null;
  71001. public static function parser(): \PHPUnit\Metadata\Parser\Parser
  71002. {
  71003. return self::$instance ?? self::$instance = self::build();
  71004. }
  71005. private static function build(): \PHPUnit\Metadata\Parser\Parser
  71006. {
  71007. return new \PHPUnit\Metadata\Parser\CachingParser(new \PHPUnit\Metadata\Parser\ParserChain(new \PHPUnit\Metadata\Parser\AttributeParser(), new \PHPUnit\Metadata\Parser\AnnotationParser()));
  71008. }
  71009. }
  71010. <?php
  71011. declare (strict_types=1);
  71012. /*
  71013. * This file is part of PHPUnit.
  71014. *
  71015. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71016. *
  71017. * For the full copyright and license information, please view the LICENSE
  71018. * file that was distributed with this source code.
  71019. */
  71020. namespace PHPUnit\Metadata;
  71021. /**
  71022. * @psalm-immutable
  71023. *
  71024. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71025. */
  71026. final class PostCondition extends \PHPUnit\Metadata\Metadata
  71027. {
  71028. /**
  71029. * @psalm-assert-if-true PostCondition $this
  71030. */
  71031. public function isPostCondition(): bool
  71032. {
  71033. return \true;
  71034. }
  71035. }
  71036. <?php
  71037. declare (strict_types=1);
  71038. /*
  71039. * This file is part of PHPUnit.
  71040. *
  71041. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71042. *
  71043. * For the full copyright and license information, please view the LICENSE
  71044. * file that was distributed with this source code.
  71045. */
  71046. namespace PHPUnit\Metadata;
  71047. /**
  71048. * @psalm-immutable
  71049. *
  71050. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71051. */
  71052. final class PreCondition extends \PHPUnit\Metadata\Metadata
  71053. {
  71054. /**
  71055. * @psalm-assert-if-true PreCondition $this
  71056. */
  71057. public function isPreCondition(): bool
  71058. {
  71059. return \true;
  71060. }
  71061. }
  71062. <?php
  71063. declare (strict_types=1);
  71064. /*
  71065. * This file is part of PHPUnit.
  71066. *
  71067. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71068. *
  71069. * For the full copyright and license information, please view the LICENSE
  71070. * file that was distributed with this source code.
  71071. */
  71072. namespace PHPUnit\Metadata;
  71073. /**
  71074. * @psalm-immutable
  71075. *
  71076. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71077. */
  71078. final class PreserveGlobalState extends \PHPUnit\Metadata\Metadata
  71079. {
  71080. private readonly bool $enabled;
  71081. /**
  71082. * @psalm-param 0|1 $level
  71083. */
  71084. protected function __construct(int $level, bool $enabled)
  71085. {
  71086. parent::__construct($level);
  71087. $this->enabled = $enabled;
  71088. }
  71089. /**
  71090. * @psalm-assert-if-true PreserveGlobalState $this
  71091. */
  71092. public function isPreserveGlobalState(): bool
  71093. {
  71094. return \true;
  71095. }
  71096. public function enabled(): bool
  71097. {
  71098. return $this->enabled;
  71099. }
  71100. }
  71101. <?php
  71102. declare (strict_types=1);
  71103. /*
  71104. * This file is part of PHPUnit.
  71105. *
  71106. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71107. *
  71108. * For the full copyright and license information, please view the LICENSE
  71109. * file that was distributed with this source code.
  71110. */
  71111. namespace PHPUnit\Metadata;
  71112. /**
  71113. * @psalm-immutable
  71114. *
  71115. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71116. */
  71117. final class RequiresFunction extends \PHPUnit\Metadata\Metadata
  71118. {
  71119. /**
  71120. * @psalm-var non-empty-string
  71121. */
  71122. private readonly string $functionName;
  71123. /**
  71124. * @psalm-param 0|1 $level
  71125. * @psalm-param non-empty-string $functionName
  71126. */
  71127. protected function __construct(int $level, string $functionName)
  71128. {
  71129. parent::__construct($level);
  71130. $this->functionName = $functionName;
  71131. }
  71132. /**
  71133. * @psalm-assert-if-true RequiresFunction $this
  71134. */
  71135. public function isRequiresFunction(): bool
  71136. {
  71137. return \true;
  71138. }
  71139. /**
  71140. * @psalm-return non-empty-string
  71141. */
  71142. public function functionName(): string
  71143. {
  71144. return $this->functionName;
  71145. }
  71146. }
  71147. <?php
  71148. declare (strict_types=1);
  71149. /*
  71150. * This file is part of PHPUnit.
  71151. *
  71152. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71153. *
  71154. * For the full copyright and license information, please view the LICENSE
  71155. * file that was distributed with this source code.
  71156. */
  71157. namespace PHPUnit\Metadata;
  71158. /**
  71159. * @psalm-immutable
  71160. *
  71161. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71162. */
  71163. final class RequiresMethod extends \PHPUnit\Metadata\Metadata
  71164. {
  71165. /**
  71166. * @psalm-var class-string
  71167. */
  71168. private readonly string $className;
  71169. /**
  71170. * @psalm-var non-empty-string
  71171. */
  71172. private readonly string $methodName;
  71173. /**
  71174. * @psalm-param 0|1 $level
  71175. * @psalm-param class-string $className
  71176. * @psalm-param non-empty-string $methodName
  71177. */
  71178. protected function __construct(int $level, string $className, string $methodName)
  71179. {
  71180. parent::__construct($level);
  71181. $this->className = $className;
  71182. $this->methodName = $methodName;
  71183. }
  71184. /**
  71185. * @psalm-assert-if-true RequiresMethod $this
  71186. */
  71187. public function isRequiresMethod(): bool
  71188. {
  71189. return \true;
  71190. }
  71191. /**
  71192. * @psalm-return class-string
  71193. */
  71194. public function className(): string
  71195. {
  71196. return $this->className;
  71197. }
  71198. /**
  71199. * @psalm-return non-empty-string
  71200. */
  71201. public function methodName(): string
  71202. {
  71203. return $this->methodName;
  71204. }
  71205. }
  71206. <?php
  71207. declare (strict_types=1);
  71208. /*
  71209. * This file is part of PHPUnit.
  71210. *
  71211. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71212. *
  71213. * For the full copyright and license information, please view the LICENSE
  71214. * file that was distributed with this source code.
  71215. */
  71216. namespace PHPUnit\Metadata;
  71217. /**
  71218. * @psalm-immutable
  71219. *
  71220. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71221. */
  71222. final class RequiresOperatingSystem extends \PHPUnit\Metadata\Metadata
  71223. {
  71224. /**
  71225. * @psalm-var non-empty-string
  71226. */
  71227. private readonly string $operatingSystem;
  71228. /**
  71229. * @psalm-param 0|1 $level
  71230. * @psalm-param non-empty-string $operatingSystem
  71231. */
  71232. public function __construct(int $level, string $operatingSystem)
  71233. {
  71234. parent::__construct($level);
  71235. $this->operatingSystem = $operatingSystem;
  71236. }
  71237. /**
  71238. * @psalm-assert-if-true RequiresOperatingSystem $this
  71239. */
  71240. public function isRequiresOperatingSystem(): bool
  71241. {
  71242. return \true;
  71243. }
  71244. /**
  71245. * @psalm-return non-empty-string
  71246. */
  71247. public function operatingSystem(): string
  71248. {
  71249. return $this->operatingSystem;
  71250. }
  71251. }
  71252. <?php
  71253. declare (strict_types=1);
  71254. /*
  71255. * This file is part of PHPUnit.
  71256. *
  71257. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71258. *
  71259. * For the full copyright and license information, please view the LICENSE
  71260. * file that was distributed with this source code.
  71261. */
  71262. namespace PHPUnit\Metadata;
  71263. /**
  71264. * @psalm-immutable
  71265. *
  71266. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71267. */
  71268. final class RequiresOperatingSystemFamily extends \PHPUnit\Metadata\Metadata
  71269. {
  71270. /**
  71271. * @psalm-var non-empty-string
  71272. */
  71273. private readonly string $operatingSystemFamily;
  71274. /**
  71275. * @psalm-param 0|1 $level
  71276. * @psalm-param non-empty-string $operatingSystemFamily
  71277. */
  71278. protected function __construct(int $level, string $operatingSystemFamily)
  71279. {
  71280. parent::__construct($level);
  71281. $this->operatingSystemFamily = $operatingSystemFamily;
  71282. }
  71283. /**
  71284. * @psalm-assert-if-true RequiresOperatingSystemFamily $this
  71285. */
  71286. public function isRequiresOperatingSystemFamily(): bool
  71287. {
  71288. return \true;
  71289. }
  71290. /**
  71291. * @psalm-return non-empty-string
  71292. */
  71293. public function operatingSystemFamily(): string
  71294. {
  71295. return $this->operatingSystemFamily;
  71296. }
  71297. }
  71298. <?php
  71299. declare (strict_types=1);
  71300. /*
  71301. * This file is part of PHPUnit.
  71302. *
  71303. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71304. *
  71305. * For the full copyright and license information, please view the LICENSE
  71306. * file that was distributed with this source code.
  71307. */
  71308. namespace PHPUnit\Metadata;
  71309. use PHPUnit\Metadata\Version\Requirement;
  71310. /**
  71311. * @psalm-immutable
  71312. *
  71313. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71314. */
  71315. final class RequiresPhp extends \PHPUnit\Metadata\Metadata
  71316. {
  71317. private readonly Requirement $versionRequirement;
  71318. /**
  71319. * @psalm-param 0|1 $level
  71320. */
  71321. protected function __construct(int $level, Requirement $versionRequirement)
  71322. {
  71323. parent::__construct($level);
  71324. $this->versionRequirement = $versionRequirement;
  71325. }
  71326. /**
  71327. * @psalm-assert-if-true RequiresPhp $this
  71328. */
  71329. public function isRequiresPhp(): bool
  71330. {
  71331. return \true;
  71332. }
  71333. public function versionRequirement(): Requirement
  71334. {
  71335. return $this->versionRequirement;
  71336. }
  71337. }
  71338. <?php
  71339. declare (strict_types=1);
  71340. /*
  71341. * This file is part of PHPUnit.
  71342. *
  71343. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71344. *
  71345. * For the full copyright and license information, please view the LICENSE
  71346. * file that was distributed with this source code.
  71347. */
  71348. namespace PHPUnit\Metadata;
  71349. use PHPUnit\Metadata\Version\Requirement;
  71350. /**
  71351. * @psalm-immutable
  71352. *
  71353. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71354. */
  71355. final class RequiresPhpExtension extends \PHPUnit\Metadata\Metadata
  71356. {
  71357. /**
  71358. * @psalm-var non-empty-string
  71359. */
  71360. private readonly string $extension;
  71361. private readonly ?Requirement $versionRequirement;
  71362. /**
  71363. * @psalm-param 0|1 $level
  71364. * @psalm-param non-empty-string $extension
  71365. */
  71366. protected function __construct(int $level, string $extension, ?Requirement $versionRequirement)
  71367. {
  71368. parent::__construct($level);
  71369. $this->extension = $extension;
  71370. $this->versionRequirement = $versionRequirement;
  71371. }
  71372. /**
  71373. * @psalm-assert-if-true RequiresPhpExtension $this
  71374. */
  71375. public function isRequiresPhpExtension(): bool
  71376. {
  71377. return \true;
  71378. }
  71379. /**
  71380. * @psalm-return non-empty-string
  71381. */
  71382. public function extension(): string
  71383. {
  71384. return $this->extension;
  71385. }
  71386. /**
  71387. * @psalm-assert-if-true !null $this->versionRequirement
  71388. */
  71389. public function hasVersionRequirement(): bool
  71390. {
  71391. return $this->versionRequirement !== null;
  71392. }
  71393. /**
  71394. * @throws NoVersionRequirementException
  71395. */
  71396. public function versionRequirement(): Requirement
  71397. {
  71398. if ($this->versionRequirement === null) {
  71399. throw new \PHPUnit\Metadata\NoVersionRequirementException();
  71400. }
  71401. return $this->versionRequirement;
  71402. }
  71403. }
  71404. <?php
  71405. declare (strict_types=1);
  71406. /*
  71407. * This file is part of PHPUnit.
  71408. *
  71409. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71410. *
  71411. * For the full copyright and license information, please view the LICENSE
  71412. * file that was distributed with this source code.
  71413. */
  71414. namespace PHPUnit\Metadata;
  71415. use PHPUnit\Metadata\Version\Requirement;
  71416. /**
  71417. * @psalm-immutable
  71418. *
  71419. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71420. */
  71421. final class RequiresPhpunit extends \PHPUnit\Metadata\Metadata
  71422. {
  71423. private readonly Requirement $versionRequirement;
  71424. /**
  71425. * @psalm-param 0|1 $level
  71426. */
  71427. protected function __construct(int $level, Requirement $versionRequirement)
  71428. {
  71429. parent::__construct($level);
  71430. $this->versionRequirement = $versionRequirement;
  71431. }
  71432. /**
  71433. * @psalm-assert-if-true RequiresPhpunit $this
  71434. */
  71435. public function isRequiresPhpunit(): bool
  71436. {
  71437. return \true;
  71438. }
  71439. public function versionRequirement(): Requirement
  71440. {
  71441. return $this->versionRequirement;
  71442. }
  71443. }
  71444. <?php
  71445. declare (strict_types=1);
  71446. /*
  71447. * This file is part of PHPUnit.
  71448. *
  71449. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71450. *
  71451. * For the full copyright and license information, please view the LICENSE
  71452. * file that was distributed with this source code.
  71453. */
  71454. namespace PHPUnit\Metadata;
  71455. /**
  71456. * @psalm-immutable
  71457. *
  71458. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71459. */
  71460. final class RequiresSetting extends \PHPUnit\Metadata\Metadata
  71461. {
  71462. /**
  71463. * @psalm-var non-empty-string
  71464. */
  71465. private readonly string $setting;
  71466. /**
  71467. * @psalm-var non-empty-string
  71468. */
  71469. private readonly string $value;
  71470. /**
  71471. * @psalm-param 0|1 $level
  71472. * @psalm-param non-empty-string $setting
  71473. * @psalm-param non-empty-string $value
  71474. */
  71475. protected function __construct(int $level, string $setting, string $value)
  71476. {
  71477. parent::__construct($level);
  71478. $this->setting = $setting;
  71479. $this->value = $value;
  71480. }
  71481. /**
  71482. * @psalm-assert-if-true RequiresSetting $this
  71483. */
  71484. public function isRequiresSetting(): bool
  71485. {
  71486. return \true;
  71487. }
  71488. /**
  71489. * @psalm-return non-empty-string
  71490. */
  71491. public function setting(): string
  71492. {
  71493. return $this->setting;
  71494. }
  71495. /**
  71496. * @psalm-return non-empty-string
  71497. */
  71498. public function value(): string
  71499. {
  71500. return $this->value;
  71501. }
  71502. }
  71503. <?php
  71504. declare (strict_types=1);
  71505. /*
  71506. * This file is part of PHPUnit.
  71507. *
  71508. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71509. *
  71510. * For the full copyright and license information, please view the LICENSE
  71511. * file that was distributed with this source code.
  71512. */
  71513. namespace PHPUnit\Metadata;
  71514. /**
  71515. * @psalm-immutable
  71516. *
  71517. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71518. */
  71519. final class RunClassInSeparateProcess extends \PHPUnit\Metadata\Metadata
  71520. {
  71521. /**
  71522. * @psalm-assert-if-true RunClassInSeparateProcess $this
  71523. */
  71524. public function isRunClassInSeparateProcess(): bool
  71525. {
  71526. return \true;
  71527. }
  71528. }
  71529. <?php
  71530. declare (strict_types=1);
  71531. /*
  71532. * This file is part of PHPUnit.
  71533. *
  71534. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71535. *
  71536. * For the full copyright and license information, please view the LICENSE
  71537. * file that was distributed with this source code.
  71538. */
  71539. namespace PHPUnit\Metadata;
  71540. /**
  71541. * @psalm-immutable
  71542. *
  71543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71544. */
  71545. final class RunInSeparateProcess extends \PHPUnit\Metadata\Metadata
  71546. {
  71547. /**
  71548. * @psalm-assert-if-true RunInSeparateProcess $this
  71549. */
  71550. public function isRunInSeparateProcess(): bool
  71551. {
  71552. return \true;
  71553. }
  71554. }
  71555. <?php
  71556. declare (strict_types=1);
  71557. /*
  71558. * This file is part of PHPUnit.
  71559. *
  71560. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71561. *
  71562. * For the full copyright and license information, please view the LICENSE
  71563. * file that was distributed with this source code.
  71564. */
  71565. namespace PHPUnit\Metadata;
  71566. /**
  71567. * @psalm-immutable
  71568. *
  71569. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71570. */
  71571. final class RunTestsInSeparateProcesses extends \PHPUnit\Metadata\Metadata
  71572. {
  71573. /**
  71574. * @psalm-assert-if-true RunTestsInSeparateProcesses $this
  71575. */
  71576. public function isRunTestsInSeparateProcesses(): bool
  71577. {
  71578. return \true;
  71579. }
  71580. }
  71581. <?php
  71582. declare (strict_types=1);
  71583. /*
  71584. * This file is part of PHPUnit.
  71585. *
  71586. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71587. *
  71588. * For the full copyright and license information, please view the LICENSE
  71589. * file that was distributed with this source code.
  71590. */
  71591. namespace PHPUnit\Metadata;
  71592. /**
  71593. * @psalm-immutable
  71594. *
  71595. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71596. */
  71597. final class Test extends \PHPUnit\Metadata\Metadata
  71598. {
  71599. /**
  71600. * @psalm-assert-if-true Test $this
  71601. */
  71602. public function isTest(): bool
  71603. {
  71604. return \true;
  71605. }
  71606. }
  71607. <?php
  71608. declare (strict_types=1);
  71609. /*
  71610. * This file is part of PHPUnit.
  71611. *
  71612. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71613. *
  71614. * For the full copyright and license information, please view the LICENSE
  71615. * file that was distributed with this source code.
  71616. */
  71617. namespace PHPUnit\Metadata;
  71618. /**
  71619. * @psalm-immutable
  71620. *
  71621. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71622. */
  71623. final class TestDox extends \PHPUnit\Metadata\Metadata
  71624. {
  71625. /**
  71626. * @psalm-var non-empty-string
  71627. */
  71628. private readonly string $text;
  71629. /**
  71630. * @psalm-param 0|1 $level
  71631. * @psalm-param non-empty-string $text
  71632. */
  71633. protected function __construct(int $level, string $text)
  71634. {
  71635. parent::__construct($level);
  71636. $this->text = $text;
  71637. }
  71638. /**
  71639. * @psalm-assert-if-true TestDox $this
  71640. */
  71641. public function isTestDox(): bool
  71642. {
  71643. return \true;
  71644. }
  71645. /**
  71646. * @psalm-return non-empty-string
  71647. */
  71648. public function text(): string
  71649. {
  71650. return $this->text;
  71651. }
  71652. }
  71653. <?php
  71654. declare (strict_types=1);
  71655. /*
  71656. * This file is part of PHPUnit.
  71657. *
  71658. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71659. *
  71660. * For the full copyright and license information, please view the LICENSE
  71661. * file that was distributed with this source code.
  71662. */
  71663. namespace PHPUnit\Metadata;
  71664. /**
  71665. * @psalm-immutable
  71666. *
  71667. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71668. */
  71669. final class TestWith extends \PHPUnit\Metadata\Metadata
  71670. {
  71671. private readonly array $data;
  71672. /**
  71673. * @psalm-param 0|1 $level
  71674. */
  71675. protected function __construct(int $level, array $data)
  71676. {
  71677. parent::__construct($level);
  71678. $this->data = $data;
  71679. }
  71680. /**
  71681. * @psalm-assert-if-true TestWith $this
  71682. */
  71683. public function isTestWith(): bool
  71684. {
  71685. return \true;
  71686. }
  71687. public function data(): array
  71688. {
  71689. return $this->data;
  71690. }
  71691. }
  71692. <?php
  71693. declare (strict_types=1);
  71694. /*
  71695. * This file is part of PHPUnit.
  71696. *
  71697. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71698. *
  71699. * For the full copyright and license information, please view the LICENSE
  71700. * file that was distributed with this source code.
  71701. */
  71702. namespace PHPUnit\Metadata;
  71703. /**
  71704. * @psalm-immutable
  71705. *
  71706. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71707. */
  71708. final class Uses extends \PHPUnit\Metadata\Metadata
  71709. {
  71710. /**
  71711. * @psalm-var non-empty-string
  71712. */
  71713. private readonly string $target;
  71714. /**
  71715. * @psalm-param 0|1 $level
  71716. * @psalm-param non-empty-string $target
  71717. */
  71718. protected function __construct(int $level, string $target)
  71719. {
  71720. parent::__construct($level);
  71721. $this->target = $target;
  71722. }
  71723. /**
  71724. * @psalm-assert-if-true Uses $this
  71725. */
  71726. public function isUses(): bool
  71727. {
  71728. return \true;
  71729. }
  71730. /**
  71731. * @psalm-return non-empty-string
  71732. */
  71733. public function target(): string
  71734. {
  71735. return $this->target;
  71736. }
  71737. }
  71738. <?php
  71739. declare (strict_types=1);
  71740. /*
  71741. * This file is part of PHPUnit.
  71742. *
  71743. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71744. *
  71745. * For the full copyright and license information, please view the LICENSE
  71746. * file that was distributed with this source code.
  71747. */
  71748. namespace PHPUnit\Metadata;
  71749. /**
  71750. * @psalm-immutable
  71751. *
  71752. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71753. */
  71754. final class UsesClass extends \PHPUnit\Metadata\Metadata
  71755. {
  71756. /**
  71757. * @psalm-var class-string
  71758. */
  71759. private readonly string $className;
  71760. /**
  71761. * @psalm-param 0|1 $level
  71762. * @psalm-param class-string $className
  71763. */
  71764. protected function __construct(int $level, string $className)
  71765. {
  71766. parent::__construct($level);
  71767. $this->className = $className;
  71768. }
  71769. /**
  71770. * @psalm-assert-if-true UsesClass $this
  71771. */
  71772. public function isUsesClass(): bool
  71773. {
  71774. return \true;
  71775. }
  71776. /**
  71777. * @psalm-return class-string
  71778. */
  71779. public function className(): string
  71780. {
  71781. return $this->className;
  71782. }
  71783. /**
  71784. * @psalm-return class-string
  71785. *
  71786. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  71787. */
  71788. public function asStringForCodeUnitMapper(): string
  71789. {
  71790. return $this->className;
  71791. }
  71792. }
  71793. <?php
  71794. declare (strict_types=1);
  71795. /*
  71796. * This file is part of PHPUnit.
  71797. *
  71798. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71799. *
  71800. * For the full copyright and license information, please view the LICENSE
  71801. * file that was distributed with this source code.
  71802. */
  71803. namespace PHPUnit\Metadata;
  71804. /**
  71805. * @psalm-immutable
  71806. *
  71807. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71808. */
  71809. final class UsesDefaultClass extends \PHPUnit\Metadata\Metadata
  71810. {
  71811. /**
  71812. * @psalm-var class-string
  71813. */
  71814. private readonly string $className;
  71815. /**
  71816. * @psalm-param 0|1 $level
  71817. * @psalm-param class-string $className
  71818. */
  71819. protected function __construct(int $level, string $className)
  71820. {
  71821. parent::__construct($level);
  71822. $this->className = $className;
  71823. }
  71824. /**
  71825. * @psalm-assert-if-true UsesDefaultClass $this
  71826. */
  71827. public function isUsesDefaultClass(): bool
  71828. {
  71829. return \true;
  71830. }
  71831. /**
  71832. * @psalm-return class-string
  71833. */
  71834. public function className(): string
  71835. {
  71836. return $this->className;
  71837. }
  71838. }
  71839. <?php
  71840. declare (strict_types=1);
  71841. /*
  71842. * This file is part of PHPUnit.
  71843. *
  71844. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71845. *
  71846. * For the full copyright and license information, please view the LICENSE
  71847. * file that was distributed with this source code.
  71848. */
  71849. namespace PHPUnit\Metadata;
  71850. /**
  71851. * @psalm-immutable
  71852. *
  71853. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71854. */
  71855. final class UsesFunction extends \PHPUnit\Metadata\Metadata
  71856. {
  71857. /**
  71858. * @psalm-var non-empty-string
  71859. */
  71860. private readonly string $functionName;
  71861. /**
  71862. * @psalm-param 0|1 $level
  71863. * @psalm-param non-empty-string $functionName
  71864. */
  71865. public function __construct(int $level, string $functionName)
  71866. {
  71867. parent::__construct($level);
  71868. $this->functionName = $functionName;
  71869. }
  71870. /**
  71871. * @psalm-assert-if-true UsesFunction $this
  71872. */
  71873. public function isUsesFunction(): bool
  71874. {
  71875. return \true;
  71876. }
  71877. /**
  71878. * @psalm-return non-empty-string
  71879. */
  71880. public function functionName(): string
  71881. {
  71882. return $this->functionName;
  71883. }
  71884. /**
  71885. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  71886. */
  71887. public function asStringForCodeUnitMapper(): string
  71888. {
  71889. return '::' . $this->functionName;
  71890. }
  71891. }
  71892. <?php
  71893. declare (strict_types=1);
  71894. /*
  71895. * This file is part of PHPUnit.
  71896. *
  71897. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71898. *
  71899. * For the full copyright and license information, please view the LICENSE
  71900. * file that was distributed with this source code.
  71901. */
  71902. namespace PHPUnit\Metadata\Version;
  71903. use function version_compare;
  71904. use PHPUnit\Util\VersionComparisonOperator;
  71905. /**
  71906. * @psalm-immutable
  71907. *
  71908. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71909. */
  71910. final class ComparisonRequirement extends \PHPUnit\Metadata\Version\Requirement
  71911. {
  71912. private readonly string $version;
  71913. private readonly VersionComparisonOperator $operator;
  71914. public function __construct(string $version, VersionComparisonOperator $operator)
  71915. {
  71916. $this->version = $version;
  71917. $this->operator = $operator;
  71918. }
  71919. public function isSatisfiedBy(string $version): bool
  71920. {
  71921. return version_compare($version, $this->version, $this->operator->asString());
  71922. }
  71923. public function asString(): string
  71924. {
  71925. return $this->operator->asString() . ' ' . $this->version;
  71926. }
  71927. }
  71928. <?php
  71929. declare (strict_types=1);
  71930. /*
  71931. * This file is part of PHPUnit.
  71932. *
  71933. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71934. *
  71935. * For the full copyright and license information, please view the LICENSE
  71936. * file that was distributed with this source code.
  71937. */
  71938. namespace PHPUnit\Metadata\Version;
  71939. use function preg_replace;
  71940. use PHPUnitPHAR\PharIo\Version\Version;
  71941. use PHPUnitPHAR\PharIo\Version\VersionConstraint;
  71942. /**
  71943. * @psalm-immutable
  71944. *
  71945. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71946. */
  71947. final class ConstraintRequirement extends \PHPUnit\Metadata\Version\Requirement
  71948. {
  71949. private readonly VersionConstraint $constraint;
  71950. public function __construct(VersionConstraint $constraint)
  71951. {
  71952. $this->constraint = $constraint;
  71953. }
  71954. /**
  71955. * @psalm-suppress ImpureMethodCall
  71956. */
  71957. public function isSatisfiedBy(string $version): bool
  71958. {
  71959. return $this->constraint->complies(new Version($this->sanitize($version)));
  71960. }
  71961. /**
  71962. * @psalm-suppress ImpureMethodCall
  71963. */
  71964. public function asString(): string
  71965. {
  71966. return $this->constraint->asString();
  71967. }
  71968. private function sanitize(string $version): string
  71969. {
  71970. return preg_replace('/^(\d+\.\d+(?:.\d+)?).*$/', '$1', $version);
  71971. }
  71972. }
  71973. <?php
  71974. declare (strict_types=1);
  71975. /*
  71976. * This file is part of PHPUnit.
  71977. *
  71978. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  71979. *
  71980. * For the full copyright and license information, please view the LICENSE
  71981. * file that was distributed with this source code.
  71982. */
  71983. namespace PHPUnit\Metadata\Version;
  71984. use function preg_match;
  71985. use PHPUnitPHAR\PharIo\Version\UnsupportedVersionConstraintException;
  71986. use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
  71987. use PHPUnit\Metadata\InvalidVersionRequirementException;
  71988. use PHPUnit\Util\InvalidVersionOperatorException;
  71989. use PHPUnit\Util\VersionComparisonOperator;
  71990. /**
  71991. * @psalm-immutable
  71992. *
  71993. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  71994. */
  71995. abstract class Requirement
  71996. {
  71997. private const VERSION_COMPARISON = '/(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
  71998. /**
  71999. * @throws InvalidVersionOperatorException
  72000. * @throws InvalidVersionRequirementException
  72001. */
  72002. public static function from(string $versionRequirement): self
  72003. {
  72004. try {
  72005. return new \PHPUnit\Metadata\Version\ConstraintRequirement((new VersionConstraintParser())->parse($versionRequirement));
  72006. } catch (UnsupportedVersionConstraintException) {
  72007. if (preg_match(self::VERSION_COMPARISON, $versionRequirement, $matches)) {
  72008. return new \PHPUnit\Metadata\Version\ComparisonRequirement($matches['version'], new VersionComparisonOperator(!empty($matches['operator']) ? $matches['operator'] : '>='));
  72009. }
  72010. }
  72011. throw new InvalidVersionRequirementException();
  72012. }
  72013. abstract public function isSatisfiedBy(string $version): bool;
  72014. abstract public function asString(): string;
  72015. }
  72016. <?php
  72017. declare (strict_types=1);
  72018. /*
  72019. * This file is part of PHPUnit.
  72020. *
  72021. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72022. *
  72023. * For the full copyright and license information, please view the LICENSE
  72024. * file that was distributed with this source code.
  72025. */
  72026. namespace PHPUnit\Metadata;
  72027. /**
  72028. * @psalm-immutable
  72029. *
  72030. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72031. */
  72032. final class WithoutErrorHandler extends \PHPUnit\Metadata\Metadata
  72033. {
  72034. /**
  72035. * @psalm-assert-if-true WithoutErrorHandler $this
  72036. */
  72037. public function isWithoutErrorHandler(): bool
  72038. {
  72039. return \true;
  72040. }
  72041. }
  72042. <?php
  72043. declare (strict_types=1);
  72044. /*
  72045. * This file is part of PHPUnit.
  72046. *
  72047. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72048. *
  72049. * For the full copyright and license information, please view the LICENSE
  72050. * file that was distributed with this source code.
  72051. */
  72052. namespace PHPUnit\Runner\Baseline;
  72053. /**
  72054. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72055. *
  72056. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72057. */
  72058. final class Baseline
  72059. {
  72060. public const VERSION = 1;
  72061. /**
  72062. * @psalm-var array<non-empty-string, array<positive-int, list<Issue>>>
  72063. */
  72064. private array $issues = [];
  72065. public function add(\PHPUnit\Runner\Baseline\Issue $issue): void
  72066. {
  72067. if (!isset($this->issues[$issue->file()])) {
  72068. $this->issues[$issue->file()] = [];
  72069. }
  72070. if (!isset($this->issues[$issue->file()][$issue->line()])) {
  72071. $this->issues[$issue->file()][$issue->line()] = [];
  72072. }
  72073. $this->issues[$issue->file()][$issue->line()][] = $issue;
  72074. }
  72075. public function has(\PHPUnit\Runner\Baseline\Issue $issue): bool
  72076. {
  72077. if (!isset($this->issues[$issue->file()][$issue->line()])) {
  72078. return \false;
  72079. }
  72080. foreach ($this->issues[$issue->file()][$issue->line()] as $_issue) {
  72081. if ($_issue->equals($issue)) {
  72082. return \true;
  72083. }
  72084. }
  72085. return \false;
  72086. }
  72087. /**
  72088. * @psalm-return array<string, array<positive-int, list<Issue>>>
  72089. */
  72090. public function groupedByFileAndLine(): array
  72091. {
  72092. return $this->issues;
  72093. }
  72094. }
  72095. <?php
  72096. declare (strict_types=1);
  72097. /*
  72098. * This file is part of PHPUnit.
  72099. *
  72100. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72101. *
  72102. * For the full copyright and license information, please view the LICENSE
  72103. * file that was distributed with this source code.
  72104. */
  72105. namespace PHPUnit\Runner\Baseline;
  72106. use PHPUnit\Runner\Exception;
  72107. use RuntimeException;
  72108. /**
  72109. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72110. *
  72111. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72112. */
  72113. final class CannotLoadBaselineException extends RuntimeException implements Exception
  72114. {
  72115. }
  72116. <?php
  72117. declare (strict_types=1);
  72118. /*
  72119. * This file is part of PHPUnit.
  72120. *
  72121. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72122. *
  72123. * For the full copyright and license information, please view the LICENSE
  72124. * file that was distributed with this source code.
  72125. */
  72126. namespace PHPUnit\Runner\Baseline;
  72127. use function sprintf;
  72128. use PHPUnit\Runner\Exception;
  72129. use RuntimeException;
  72130. /**
  72131. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72132. *
  72133. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72134. */
  72135. final class FileDoesNotHaveLineException extends RuntimeException implements Exception
  72136. {
  72137. public function __construct(string $file, int $line)
  72138. {
  72139. parent::__construct(sprintf('File "%s" does not have line %d', $file, $line));
  72140. }
  72141. }
  72142. <?php
  72143. declare (strict_types=1);
  72144. /*
  72145. * This file is part of PHPUnit.
  72146. *
  72147. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72148. *
  72149. * For the full copyright and license information, please view the LICENSE
  72150. * file that was distributed with this source code.
  72151. */
  72152. namespace PHPUnit\Runner\Baseline;
  72153. use PHPUnit\Event\EventFacadeIsSealedException;
  72154. use PHPUnit\Event\Facade;
  72155. use PHPUnit\Event\Test\DeprecationTriggered;
  72156. use PHPUnit\Event\Test\NoticeTriggered;
  72157. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  72158. use PHPUnit\Event\Test\PhpNoticeTriggered;
  72159. use PHPUnit\Event\Test\PhpWarningTriggered;
  72160. use PHPUnit\Event\Test\WarningTriggered;
  72161. use PHPUnit\Event\UnknownSubscriberTypeException;
  72162. use PHPUnit\Runner\FileDoesNotExistException;
  72163. use PHPUnit\TextUI\Configuration\Source;
  72164. use PHPUnit\TextUI\Configuration\SourceFilter;
  72165. /**
  72166. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72167. *
  72168. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72169. */
  72170. final class Generator
  72171. {
  72172. private \PHPUnit\Runner\Baseline\Baseline $baseline;
  72173. private readonly Source $source;
  72174. /**
  72175. * @throws EventFacadeIsSealedException
  72176. * @throws UnknownSubscriberTypeException
  72177. */
  72178. public function __construct(Facade $facade, Source $source)
  72179. {
  72180. $facade->registerSubscribers(new \PHPUnit\Runner\Baseline\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredNoticeSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredWarningSubscriber($this));
  72181. $this->baseline = new \PHPUnit\Runner\Baseline\Baseline();
  72182. $this->source = $source;
  72183. }
  72184. public function baseline(): \PHPUnit\Runner\Baseline\Baseline
  72185. {
  72186. return $this->baseline;
  72187. }
  72188. /**
  72189. * @throws FileDoesNotExistException
  72190. * @throws FileDoesNotHaveLineException
  72191. */
  72192. public function testTriggeredIssue(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): void
  72193. {
  72194. if ($event->wasSuppressed() && !$this->isSuppressionIgnored($event)) {
  72195. return;
  72196. }
  72197. if ($this->restrict($event) && !(new SourceFilter())->includes($this->source, $event->file())) {
  72198. return;
  72199. }
  72200. $this->baseline->add(\PHPUnit\Runner\Baseline\Issue::from($event->file(), $event->line(), null, $event->message()));
  72201. }
  72202. private function restrict(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): bool
  72203. {
  72204. if ($event instanceof WarningTriggered || $event instanceof PhpWarningTriggered) {
  72205. return $this->source->restrictWarnings();
  72206. }
  72207. if ($event instanceof NoticeTriggered || $event instanceof PhpNoticeTriggered) {
  72208. return $this->source->restrictNotices();
  72209. }
  72210. return $this->source->restrictDeprecations();
  72211. }
  72212. private function isSuppressionIgnored(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): bool
  72213. {
  72214. if ($event instanceof WarningTriggered) {
  72215. return $this->source->ignoreSuppressionOfWarnings();
  72216. }
  72217. if ($event instanceof PhpWarningTriggered) {
  72218. return $this->source->ignoreSuppressionOfPhpWarnings();
  72219. }
  72220. if ($event instanceof PhpNoticeTriggered) {
  72221. return $this->source->ignoreSuppressionOfPhpNotices();
  72222. }
  72223. if ($event instanceof NoticeTriggered) {
  72224. return $this->source->ignoreSuppressionOfNotices();
  72225. }
  72226. if ($event instanceof PhpDeprecationTriggered) {
  72227. return $this->source->ignoreSuppressionOfPhpDeprecations();
  72228. }
  72229. return $this->source->ignoreSuppressionOfDeprecations();
  72230. }
  72231. }
  72232. <?php
  72233. declare (strict_types=1);
  72234. /*
  72235. * This file is part of PHPUnit.
  72236. *
  72237. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72238. *
  72239. * For the full copyright and license information, please view the LICENSE
  72240. * file that was distributed with this source code.
  72241. */
  72242. namespace PHPUnit\Runner\Baseline;
  72243. use const FILE_IGNORE_NEW_LINES;
  72244. use function assert;
  72245. use function file;
  72246. use function is_file;
  72247. use function sha1;
  72248. use PHPUnit\Runner\FileDoesNotExistException;
  72249. /**
  72250. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72251. *
  72252. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72253. */
  72254. final class Issue
  72255. {
  72256. /**
  72257. * @psalm-var non-empty-string
  72258. */
  72259. private readonly string $file;
  72260. /**
  72261. * @psalm-var positive-int
  72262. */
  72263. private readonly int $line;
  72264. /**
  72265. * @psalm-var non-empty-string
  72266. */
  72267. private readonly string $hash;
  72268. /**
  72269. * @psalm-var non-empty-string
  72270. */
  72271. private readonly string $description;
  72272. /**
  72273. * @psalm-param non-empty-string $file
  72274. * @psalm-param positive-int $line
  72275. * @psalm-param ?non-empty-string $hash
  72276. * @psalm-param non-empty-string $description
  72277. *
  72278. * @throws FileDoesNotExistException
  72279. * @throws FileDoesNotHaveLineException
  72280. */
  72281. public static function from(string $file, int $line, ?string $hash, string $description): self
  72282. {
  72283. if ($hash === null) {
  72284. $hash = self::calculateHash($file, $line);
  72285. }
  72286. return new self($file, $line, $hash, $description);
  72287. }
  72288. /**
  72289. * @psalm-param non-empty-string $file
  72290. * @psalm-param positive-int $line
  72291. * @psalm-param non-empty-string $hash
  72292. * @psalm-param non-empty-string $description
  72293. */
  72294. private function __construct(string $file, int $line, string $hash, string $description)
  72295. {
  72296. $this->file = $file;
  72297. $this->line = $line;
  72298. $this->hash = $hash;
  72299. $this->description = $description;
  72300. }
  72301. /**
  72302. * @psalm-return non-empty-string
  72303. */
  72304. public function file(): string
  72305. {
  72306. return $this->file;
  72307. }
  72308. /**
  72309. * @psalm-return positive-int
  72310. */
  72311. public function line(): int
  72312. {
  72313. return $this->line;
  72314. }
  72315. /**
  72316. * @psalm-return non-empty-string
  72317. */
  72318. public function hash(): string
  72319. {
  72320. return $this->hash;
  72321. }
  72322. /**
  72323. * @psalm-return non-empty-string
  72324. */
  72325. public function description(): string
  72326. {
  72327. return $this->description;
  72328. }
  72329. public function equals(self $other): bool
  72330. {
  72331. return $this->file() === $other->file() && $this->line() === $other->line() && $this->hash() === $other->hash() && $this->description() === $other->description();
  72332. }
  72333. /**
  72334. * @psalm-param non-empty-string $file
  72335. * @psalm-param positive-int $line
  72336. *
  72337. * @psalm-return non-empty-string
  72338. *
  72339. * @throws FileDoesNotExistException
  72340. * @throws FileDoesNotHaveLineException
  72341. */
  72342. private static function calculateHash(string $file, int $line): string
  72343. {
  72344. $lines = @file($file, FILE_IGNORE_NEW_LINES);
  72345. if ($lines === \false && !is_file($file)) {
  72346. throw new FileDoesNotExistException($file);
  72347. }
  72348. $key = $line - 1;
  72349. if (!isset($lines[$key])) {
  72350. throw new \PHPUnit\Runner\Baseline\FileDoesNotHaveLineException($file, $line);
  72351. }
  72352. $hash = sha1($lines[$key]);
  72353. assert($hash !== '');
  72354. return $hash;
  72355. }
  72356. }
  72357. <?php
  72358. declare (strict_types=1);
  72359. /*
  72360. * This file is part of PHPUnit.
  72361. *
  72362. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72363. *
  72364. * For the full copyright and license information, please view the LICENSE
  72365. * file that was distributed with this source code.
  72366. */
  72367. namespace PHPUnit\Runner\Baseline;
  72368. use const DIRECTORY_SEPARATOR;
  72369. use function assert;
  72370. use function dirname;
  72371. use function is_file;
  72372. use function realpath;
  72373. use function sprintf;
  72374. use function str_replace;
  72375. use function trim;
  72376. use DOMElement;
  72377. use DOMXPath;
  72378. use PHPUnit\Util\Xml\Loader as XmlLoader;
  72379. use PHPUnit\Util\Xml\XmlException;
  72380. /**
  72381. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72382. *
  72383. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72384. */
  72385. final class Reader
  72386. {
  72387. /**
  72388. * @psalm-param non-empty-string $baselineFile
  72389. *
  72390. * @throws CannotLoadBaselineException
  72391. */
  72392. public function read(string $baselineFile): \PHPUnit\Runner\Baseline\Baseline
  72393. {
  72394. if (!is_file($baselineFile)) {
  72395. throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline %s, file does not exist', $baselineFile));
  72396. }
  72397. try {
  72398. $document = (new XmlLoader())->loadFile($baselineFile);
  72399. } catch (XmlException $e) {
  72400. throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline: %s', trim($e->getMessage())));
  72401. }
  72402. $version = (int) $document->documentElement->getAttribute('version');
  72403. if ($version !== \PHPUnit\Runner\Baseline\Baseline::VERSION) {
  72404. throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline %s, version %d is not supported', $baselineFile, $version));
  72405. }
  72406. $baseline = new \PHPUnit\Runner\Baseline\Baseline();
  72407. $baselineDirectory = dirname(realpath($baselineFile));
  72408. $xpath = new DOMXPath($document);
  72409. foreach ($xpath->query('file') as $fileElement) {
  72410. assert($fileElement instanceof DOMElement);
  72411. $file = $baselineDirectory . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $fileElement->getAttribute('path'));
  72412. foreach ($xpath->query('line', $fileElement) as $lineElement) {
  72413. assert($lineElement instanceof DOMElement);
  72414. $line = (int) $lineElement->getAttribute('number');
  72415. $hash = $lineElement->getAttribute('hash');
  72416. foreach ($xpath->query('issue', $lineElement) as $issueElement) {
  72417. assert($issueElement instanceof DOMElement);
  72418. $description = $issueElement->textContent;
  72419. assert($line > 0);
  72420. assert(!empty($hash));
  72421. assert(!empty($description));
  72422. $baseline->add(\PHPUnit\Runner\Baseline\Issue::from($file, $line, $hash, $description));
  72423. }
  72424. }
  72425. }
  72426. return $baseline;
  72427. }
  72428. }
  72429. <?php
  72430. declare (strict_types=1);
  72431. /*
  72432. * This file is part of PHPUnit.
  72433. *
  72434. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72435. *
  72436. * For the full copyright and license information, please view the LICENSE
  72437. * file that was distributed with this source code.
  72438. */
  72439. namespace PHPUnit\Runner\Baseline;
  72440. use function array_fill;
  72441. use function array_merge;
  72442. use function array_slice;
  72443. use function assert;
  72444. use function count;
  72445. use function explode;
  72446. use function implode;
  72447. use function str_replace;
  72448. use function strpos;
  72449. use function substr;
  72450. use function trim;
  72451. /**
  72452. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72453. *
  72454. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72455. *
  72456. * @see Copied from https://github.com/phpstan/phpstan-src/blob/1.10.33/src/File/ParentDirectoryRelativePathHelper.php
  72457. */
  72458. final class RelativePathCalculator
  72459. {
  72460. /**
  72461. * @psalm-var non-empty-string $baselineDirectory
  72462. */
  72463. private readonly string $baselineDirectory;
  72464. /**
  72465. * @psalm-param non-empty-string $baselineDirectory
  72466. */
  72467. public function __construct(string $baselineDirectory)
  72468. {
  72469. $this->baselineDirectory = $baselineDirectory;
  72470. }
  72471. /**
  72472. * @psalm-param non-empty-string $filename
  72473. *
  72474. * @psalm-return non-empty-string
  72475. */
  72476. public function calculate(string $filename): string
  72477. {
  72478. $result = implode('/', $this->parts($filename));
  72479. assert($result !== '');
  72480. return $result;
  72481. }
  72482. /**
  72483. * @psalm-param non-empty-string $filename
  72484. *
  72485. * @psalm-return list<non-empty-string>
  72486. */
  72487. public function parts(string $filename): array
  72488. {
  72489. $schemePosition = strpos($filename, '://');
  72490. if ($schemePosition !== \false) {
  72491. $filename = substr($filename, $schemePosition + 3);
  72492. assert($filename !== '');
  72493. }
  72494. $parentParts = explode('/', trim(str_replace('\\', '/', $this->baselineDirectory), '/'));
  72495. $parentPartsCount = count($parentParts);
  72496. $filenameParts = explode('/', trim(str_replace('\\', '/', $filename), '/'));
  72497. $filenamePartsCount = count($filenameParts);
  72498. $i = 0;
  72499. for (; $i < $filenamePartsCount; $i++) {
  72500. if ($parentPartsCount < $i + 1) {
  72501. break;
  72502. }
  72503. $parentPath = implode('/', array_slice($parentParts, 0, $i + 1));
  72504. $filenamePath = implode('/', array_slice($filenameParts, 0, $i + 1));
  72505. if ($parentPath !== $filenamePath) {
  72506. break;
  72507. }
  72508. }
  72509. if ($i === 0) {
  72510. return [$filename];
  72511. }
  72512. $dotsCount = $parentPartsCount - $i;
  72513. assert($dotsCount >= 0);
  72514. return array_merge(array_fill(0, $dotsCount, '..'), array_slice($filenameParts, $i));
  72515. }
  72516. }
  72517. <?php
  72518. declare (strict_types=1);
  72519. /*
  72520. * This file is part of PHPUnit.
  72521. *
  72522. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72523. *
  72524. * For the full copyright and license information, please view the LICENSE
  72525. * file that was distributed with this source code.
  72526. */
  72527. namespace PHPUnit\Runner\Baseline;
  72528. /**
  72529. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72530. *
  72531. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72532. */
  72533. abstract class Subscriber
  72534. {
  72535. private readonly \PHPUnit\Runner\Baseline\Generator $generator;
  72536. public function __construct(\PHPUnit\Runner\Baseline\Generator $generator)
  72537. {
  72538. $this->generator = $generator;
  72539. }
  72540. protected function generator(): \PHPUnit\Runner\Baseline\Generator
  72541. {
  72542. return $this->generator;
  72543. }
  72544. }
  72545. <?php
  72546. declare (strict_types=1);
  72547. /*
  72548. * This file is part of PHPUnit.
  72549. *
  72550. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72551. *
  72552. * For the full copyright and license information, please view the LICENSE
  72553. * file that was distributed with this source code.
  72554. */
  72555. namespace PHPUnit\Runner\Baseline;
  72556. use PHPUnit\Event\Test\DeprecationTriggered;
  72557. use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
  72558. use PHPUnit\Runner\FileDoesNotExistException;
  72559. /**
  72560. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72561. *
  72562. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72563. */
  72564. final class TestTriggeredDeprecationSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements DeprecationTriggeredSubscriber
  72565. {
  72566. /**
  72567. * @throws FileDoesNotExistException
  72568. * @throws FileDoesNotHaveLineException
  72569. */
  72570. public function notify(DeprecationTriggered $event): void
  72571. {
  72572. $this->generator()->testTriggeredIssue($event);
  72573. }
  72574. }
  72575. <?php
  72576. declare (strict_types=1);
  72577. /*
  72578. * This file is part of PHPUnit.
  72579. *
  72580. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72581. *
  72582. * For the full copyright and license information, please view the LICENSE
  72583. * file that was distributed with this source code.
  72584. */
  72585. namespace PHPUnit\Runner\Baseline;
  72586. use PHPUnit\Event\Test\NoticeTriggered;
  72587. use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
  72588. use PHPUnit\Runner\FileDoesNotExistException;
  72589. /**
  72590. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72591. *
  72592. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72593. */
  72594. final class TestTriggeredNoticeSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements NoticeTriggeredSubscriber
  72595. {
  72596. /**
  72597. * @throws FileDoesNotExistException
  72598. * @throws FileDoesNotHaveLineException
  72599. */
  72600. public function notify(NoticeTriggered $event): void
  72601. {
  72602. $this->generator()->testTriggeredIssue($event);
  72603. }
  72604. }
  72605. <?php
  72606. declare (strict_types=1);
  72607. /*
  72608. * This file is part of PHPUnit.
  72609. *
  72610. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72611. *
  72612. * For the full copyright and license information, please view the LICENSE
  72613. * file that was distributed with this source code.
  72614. */
  72615. namespace PHPUnit\Runner\Baseline;
  72616. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  72617. use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
  72618. use PHPUnit\Runner\FileDoesNotExistException;
  72619. /**
  72620. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72621. *
  72622. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72623. */
  72624. final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpDeprecationTriggeredSubscriber
  72625. {
  72626. /**
  72627. * @throws FileDoesNotExistException
  72628. * @throws FileDoesNotHaveLineException
  72629. */
  72630. public function notify(PhpDeprecationTriggered $event): void
  72631. {
  72632. $this->generator()->testTriggeredIssue($event);
  72633. }
  72634. }
  72635. <?php
  72636. declare (strict_types=1);
  72637. /*
  72638. * This file is part of PHPUnit.
  72639. *
  72640. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72641. *
  72642. * For the full copyright and license information, please view the LICENSE
  72643. * file that was distributed with this source code.
  72644. */
  72645. namespace PHPUnit\Runner\Baseline;
  72646. use PHPUnit\Event\Test\PhpNoticeTriggered;
  72647. use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
  72648. use PHPUnit\Runner\FileDoesNotExistException;
  72649. /**
  72650. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72651. *
  72652. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72653. */
  72654. final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpNoticeTriggeredSubscriber
  72655. {
  72656. /**
  72657. * @throws FileDoesNotExistException
  72658. * @throws FileDoesNotHaveLineException
  72659. */
  72660. public function notify(PhpNoticeTriggered $event): void
  72661. {
  72662. $this->generator()->testTriggeredIssue($event);
  72663. }
  72664. }
  72665. <?php
  72666. declare (strict_types=1);
  72667. /*
  72668. * This file is part of PHPUnit.
  72669. *
  72670. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72671. *
  72672. * For the full copyright and license information, please view the LICENSE
  72673. * file that was distributed with this source code.
  72674. */
  72675. namespace PHPUnit\Runner\Baseline;
  72676. use PHPUnit\Event\Test\PhpWarningTriggered;
  72677. use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
  72678. use PHPUnit\Runner\FileDoesNotExistException;
  72679. /**
  72680. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72681. *
  72682. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72683. */
  72684. final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpWarningTriggeredSubscriber
  72685. {
  72686. /**
  72687. * @throws FileDoesNotExistException
  72688. * @throws FileDoesNotHaveLineException
  72689. */
  72690. public function notify(PhpWarningTriggered $event): void
  72691. {
  72692. $this->generator()->testTriggeredIssue($event);
  72693. }
  72694. }
  72695. <?php
  72696. declare (strict_types=1);
  72697. /*
  72698. * This file is part of PHPUnit.
  72699. *
  72700. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72701. *
  72702. * For the full copyright and license information, please view the LICENSE
  72703. * file that was distributed with this source code.
  72704. */
  72705. namespace PHPUnit\Runner\Baseline;
  72706. use PHPUnit\Event\Test\WarningTriggered;
  72707. use PHPUnit\Event\Test\WarningTriggeredSubscriber;
  72708. use PHPUnit\Runner\FileDoesNotExistException;
  72709. /**
  72710. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72711. *
  72712. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72713. */
  72714. final class TestTriggeredWarningSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements WarningTriggeredSubscriber
  72715. {
  72716. /**
  72717. * @throws FileDoesNotExistException
  72718. * @throws FileDoesNotHaveLineException
  72719. */
  72720. public function notify(WarningTriggered $event): void
  72721. {
  72722. $this->generator()->testTriggeredIssue($event);
  72723. }
  72724. }
  72725. <?php
  72726. declare (strict_types=1);
  72727. /*
  72728. * This file is part of PHPUnit.
  72729. *
  72730. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72731. *
  72732. * For the full copyright and license information, please view the LICENSE
  72733. * file that was distributed with this source code.
  72734. */
  72735. namespace PHPUnit\Runner\Baseline;
  72736. use function assert;
  72737. use function dirname;
  72738. use function file_put_contents;
  72739. use XMLWriter;
  72740. /**
  72741. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72742. *
  72743. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72744. */
  72745. final class Writer
  72746. {
  72747. /**
  72748. * @psalm-param non-empty-string $baselineFile
  72749. */
  72750. public function write(string $baselineFile, \PHPUnit\Runner\Baseline\Baseline $baseline): void
  72751. {
  72752. $pathCalculator = new \PHPUnit\Runner\Baseline\RelativePathCalculator(dirname($baselineFile));
  72753. $writer = new XMLWriter();
  72754. $writer->openMemory();
  72755. $writer->setIndent(\true);
  72756. $writer->startDocument();
  72757. $writer->startElement('files');
  72758. $writer->writeAttribute('version', (string) \PHPUnit\Runner\Baseline\Baseline::VERSION);
  72759. foreach ($baseline->groupedByFileAndLine() as $file => $lines) {
  72760. assert(!empty($file));
  72761. $writer->startElement('file');
  72762. $writer->writeAttribute('path', $pathCalculator->calculate($file));
  72763. foreach ($lines as $line => $issues) {
  72764. $writer->startElement('line');
  72765. $writer->writeAttribute('number', (string) $line);
  72766. $writer->writeAttribute('hash', $issues[0]->hash());
  72767. foreach ($issues as $issue) {
  72768. $writer->startElement('issue');
  72769. $writer->writeCData($issue->description());
  72770. $writer->endElement();
  72771. }
  72772. $writer->endElement();
  72773. }
  72774. $writer->endElement();
  72775. }
  72776. $writer->endElement();
  72777. file_put_contents($baselineFile, $writer->outputMemory());
  72778. }
  72779. }
  72780. <?php
  72781. declare (strict_types=1);
  72782. /*
  72783. * This file is part of PHPUnit.
  72784. *
  72785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  72786. *
  72787. * For the full copyright and license information, please view the LICENSE
  72788. * file that was distributed with this source code.
  72789. */
  72790. namespace PHPUnit\Runner;
  72791. use function file_put_contents;
  72792. use function sprintf;
  72793. use PHPUnit\Event\Facade as EventFacade;
  72794. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  72795. use PHPUnit\Framework\TestCase;
  72796. use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
  72797. use PHPUnit\TextUI\Configuration\Configuration;
  72798. use PHPUnit\TextUI\Output\Printer;
  72799. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
  72800. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Selector;
  72801. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception as CodeCoverageException;
  72802. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  72803. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Clover as CloverReport;
  72804. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Cobertura as CoberturaReport;
  72805. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport;
  72806. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
  72807. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\CustomCssFile;
  72808. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;
  72809. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\PHP as PhpReport;
  72810. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Text as TextReport;
  72811. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
  72812. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport;
  72813. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
  72814. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
  72815. use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
  72816. use PHPUnitPHAR\SebastianBergmann\Timer\NoActiveTimerException;
  72817. use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
  72818. /**
  72819. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  72820. *
  72821. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  72822. *
  72823. * @codeCoverageIgnore
  72824. */
  72825. final class CodeCoverage
  72826. {
  72827. private static ?self $instance = null;
  72828. private ?\PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage $codeCoverage = null;
  72829. private ?Driver $driver = null;
  72830. private bool $collecting = \false;
  72831. private ?TestCase $test = null;
  72832. private ?Timer $timer = null;
  72833. /**
  72834. * @psalm-var array<string,list<int>>
  72835. */
  72836. private array $linesToBeIgnored = [];
  72837. public static function instance(): self
  72838. {
  72839. if (self::$instance === null) {
  72840. self::$instance = new self();
  72841. }
  72842. return self::$instance;
  72843. }
  72844. public function init(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry, bool $extensionRequiresCodeCoverageCollection): void
  72845. {
  72846. $codeCoverageFilterRegistry->init($configuration);
  72847. if (!$configuration->hasCoverageReport() && !$extensionRequiresCodeCoverageCollection) {
  72848. return;
  72849. }
  72850. $this->activate($codeCoverageFilterRegistry->get(), $configuration->pathCoverage());
  72851. if (!$this->isActive()) {
  72852. return;
  72853. }
  72854. if ($configuration->hasCoverageCacheDirectory()) {
  72855. $this->codeCoverage()->cacheStaticAnalysis($configuration->coverageCacheDirectory());
  72856. }
  72857. $this->codeCoverage()->excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(Comparator::class);
  72858. if ($configuration->strictCoverage()) {
  72859. $this->codeCoverage()->enableCheckForUnintentionallyCoveredCode();
  72860. }
  72861. if ($configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage()) {
  72862. $this->codeCoverage()->ignoreDeprecatedCode();
  72863. } else {
  72864. $this->codeCoverage()->doNotIgnoreDeprecatedCode();
  72865. }
  72866. if ($configuration->disableCodeCoverageIgnore()) {
  72867. $this->codeCoverage()->disableAnnotationsForIgnoringCode();
  72868. } else {
  72869. $this->codeCoverage()->enableAnnotationsForIgnoringCode();
  72870. }
  72871. if ($configuration->includeUncoveredFiles()) {
  72872. $this->codeCoverage()->includeUncoveredFiles();
  72873. } else {
  72874. $this->codeCoverage()->excludeUncoveredFiles();
  72875. }
  72876. if ($codeCoverageFilterRegistry->get()->isEmpty()) {
  72877. if (!$codeCoverageFilterRegistry->configured()) {
  72878. EventFacade::emitter()->testRunnerTriggeredWarning('No filter is configured, code coverage will not be processed');
  72879. } else {
  72880. EventFacade::emitter()->testRunnerTriggeredWarning('Incorrect filter configuration, code coverage will not be processed');
  72881. }
  72882. $this->deactivate();
  72883. }
  72884. }
  72885. /**
  72886. * @psalm-assert-if-true !null $this->instance
  72887. */
  72888. public function isActive(): bool
  72889. {
  72890. return $this->codeCoverage !== null;
  72891. }
  72892. public function codeCoverage(): \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage
  72893. {
  72894. return $this->codeCoverage;
  72895. }
  72896. public function driver(): Driver
  72897. {
  72898. return $this->driver;
  72899. }
  72900. /**
  72901. * @throws MoreThanOneDataSetFromDataProviderException
  72902. */
  72903. public function start(TestCase $test): void
  72904. {
  72905. if ($this->collecting) {
  72906. return;
  72907. }
  72908. $size = TestSize::unknown();
  72909. if ($test->size()->isSmall()) {
  72910. $size = TestSize::small();
  72911. } elseif ($test->size()->isMedium()) {
  72912. $size = TestSize::medium();
  72913. } elseif ($test->size()->isLarge()) {
  72914. $size = TestSize::large();
  72915. }
  72916. $this->test = $test;
  72917. $this->codeCoverage->start($test->valueObjectForEvents()->id(), $size);
  72918. $this->collecting = \true;
  72919. }
  72920. public function stop(bool $append, array|false $linesToBeCovered = [], array $linesToBeUsed = []): void
  72921. {
  72922. if (!$this->collecting) {
  72923. return;
  72924. }
  72925. $status = TestStatus::unknown();
  72926. if ($this->test !== null) {
  72927. if ($this->test->status()->isSuccess()) {
  72928. $status = TestStatus::success();
  72929. } else {
  72930. $status = TestStatus::failure();
  72931. }
  72932. }
  72933. /* @noinspection UnusedFunctionResultInspection */
  72934. $this->codeCoverage->stop($append, $status, $linesToBeCovered, $linesToBeUsed, $this->linesToBeIgnored);
  72935. $this->test = null;
  72936. $this->collecting = \false;
  72937. }
  72938. public function deactivate(): void
  72939. {
  72940. $this->driver = null;
  72941. $this->codeCoverage = null;
  72942. $this->test = null;
  72943. }
  72944. public function generateReports(Printer $printer, Configuration $configuration): void
  72945. {
  72946. if (!$this->isActive()) {
  72947. return;
  72948. }
  72949. if ($configuration->hasCoveragePhp()) {
  72950. $this->codeCoverageGenerationStart($printer, 'PHP');
  72951. try {
  72952. $writer = new PhpReport();
  72953. $writer->process($this->codeCoverage(), $configuration->coveragePhp());
  72954. $this->codeCoverageGenerationSucceeded($printer);
  72955. unset($writer);
  72956. } catch (CodeCoverageException $e) {
  72957. $this->codeCoverageGenerationFailed($printer, $e);
  72958. }
  72959. }
  72960. if ($configuration->hasCoverageClover()) {
  72961. $this->codeCoverageGenerationStart($printer, 'Clover XML');
  72962. try {
  72963. $writer = new CloverReport();
  72964. $writer->process($this->codeCoverage(), $configuration->coverageClover());
  72965. $this->codeCoverageGenerationSucceeded($printer);
  72966. unset($writer);
  72967. } catch (CodeCoverageException $e) {
  72968. $this->codeCoverageGenerationFailed($printer, $e);
  72969. }
  72970. }
  72971. if ($configuration->hasCoverageCobertura()) {
  72972. $this->codeCoverageGenerationStart($printer, 'Cobertura XML');
  72973. try {
  72974. $writer = new CoberturaReport();
  72975. $writer->process($this->codeCoverage(), $configuration->coverageCobertura());
  72976. $this->codeCoverageGenerationSucceeded($printer);
  72977. unset($writer);
  72978. } catch (CodeCoverageException $e) {
  72979. $this->codeCoverageGenerationFailed($printer, $e);
  72980. }
  72981. }
  72982. if ($configuration->hasCoverageCrap4j()) {
  72983. $this->codeCoverageGenerationStart($printer, 'Crap4J XML');
  72984. try {
  72985. $writer = new Crap4jReport($configuration->coverageCrap4jThreshold());
  72986. $writer->process($this->codeCoverage(), $configuration->coverageCrap4j());
  72987. $this->codeCoverageGenerationSucceeded($printer);
  72988. unset($writer);
  72989. } catch (CodeCoverageException $e) {
  72990. $this->codeCoverageGenerationFailed($printer, $e);
  72991. }
  72992. }
  72993. if ($configuration->hasCoverageHtml()) {
  72994. $this->codeCoverageGenerationStart($printer, 'HTML');
  72995. try {
  72996. $customCssFile = CustomCssFile::default();
  72997. if ($configuration->hasCoverageHtmlCustomCssFile()) {
  72998. $customCssFile = CustomCssFile::from($configuration->coverageHtmlCustomCssFile());
  72999. }
  73000. $writer = new HtmlReport(sprintf(' and <a href="https://phpunit.de/">PHPUnit %s</a>', \PHPUnit\Runner\Version::id()), Colors::from($configuration->coverageHtmlColorSuccessLow(), $configuration->coverageHtmlColorSuccessMedium(), $configuration->coverageHtmlColorSuccessHigh(), $configuration->coverageHtmlColorWarning(), $configuration->coverageHtmlColorDanger()), Thresholds::from($configuration->coverageHtmlLowUpperBound(), $configuration->coverageHtmlHighLowerBound()), $customCssFile);
  73001. $writer->process($this->codeCoverage(), $configuration->coverageHtml());
  73002. $this->codeCoverageGenerationSucceeded($printer);
  73003. unset($writer);
  73004. } catch (CodeCoverageException $e) {
  73005. $this->codeCoverageGenerationFailed($printer, $e);
  73006. }
  73007. }
  73008. if ($configuration->hasCoverageText()) {
  73009. $processor = new TextReport(Thresholds::default(), $configuration->coverageTextShowUncoveredFiles(), $configuration->coverageTextShowOnlySummary());
  73010. $textReport = $processor->process($this->codeCoverage(), $configuration->colors());
  73011. if ($configuration->coverageText() === 'php://stdout') {
  73012. if (!$configuration->noOutput() && !$configuration->debug()) {
  73013. $printer->print($textReport);
  73014. }
  73015. } else {
  73016. file_put_contents($configuration->coverageText(), $textReport);
  73017. }
  73018. }
  73019. if ($configuration->hasCoverageXml()) {
  73020. $this->codeCoverageGenerationStart($printer, 'PHPUnit XML');
  73021. try {
  73022. $writer = new XmlReport(\PHPUnit\Runner\Version::id());
  73023. $writer->process($this->codeCoverage(), $configuration->coverageXml());
  73024. $this->codeCoverageGenerationSucceeded($printer);
  73025. unset($writer);
  73026. } catch (CodeCoverageException $e) {
  73027. $this->codeCoverageGenerationFailed($printer, $e);
  73028. }
  73029. }
  73030. }
  73031. /**
  73032. * @psalm-param array<string,list<int>> $linesToBeIgnored
  73033. */
  73034. public function ignoreLines(array $linesToBeIgnored): void
  73035. {
  73036. $this->linesToBeIgnored = $linesToBeIgnored;
  73037. }
  73038. /**
  73039. * @psalm-return array<string,list<int>>
  73040. */
  73041. public function linesToBeIgnored(): array
  73042. {
  73043. return $this->linesToBeIgnored;
  73044. }
  73045. private function activate(Filter $filter, bool $pathCoverage): void
  73046. {
  73047. try {
  73048. if ($pathCoverage) {
  73049. $this->driver = (new Selector())->forLineAndPathCoverage($filter);
  73050. } else {
  73051. $this->driver = (new Selector())->forLineCoverage($filter);
  73052. }
  73053. $this->codeCoverage = new \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage($this->driver, $filter);
  73054. } catch (CodeCoverageException $e) {
  73055. EventFacade::emitter()->testRunnerTriggeredWarning($e->getMessage());
  73056. }
  73057. }
  73058. private function codeCoverageGenerationStart(Printer $printer, string $format): void
  73059. {
  73060. $printer->print(sprintf("\nGenerating code coverage report in %s format ... ", $format));
  73061. $this->timer()->start();
  73062. }
  73063. /**
  73064. * @throws NoActiveTimerException
  73065. */
  73066. private function codeCoverageGenerationSucceeded(Printer $printer): void
  73067. {
  73068. $printer->print(sprintf("done [%s]\n", $this->timer()->stop()->asString()));
  73069. }
  73070. /**
  73071. * @throws NoActiveTimerException
  73072. */
  73073. private function codeCoverageGenerationFailed(Printer $printer, CodeCoverageException $e): void
  73074. {
  73075. $printer->print(sprintf("failed [%s]\n%s\n", $this->timer()->stop()->asString(), $e->getMessage()));
  73076. }
  73077. private function timer(): Timer
  73078. {
  73079. if ($this->timer === null) {
  73080. $this->timer = new Timer();
  73081. }
  73082. return $this->timer;
  73083. }
  73084. }
  73085. <?php
  73086. declare (strict_types=1);
  73087. /*
  73088. * This file is part of PHPUnit.
  73089. *
  73090. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73091. *
  73092. * For the full copyright and license information, please view the LICENSE
  73093. * file that was distributed with this source code.
  73094. */
  73095. namespace PHPUnit\Runner;
  73096. use const E_COMPILE_ERROR;
  73097. use const E_COMPILE_WARNING;
  73098. use const E_CORE_ERROR;
  73099. use const E_CORE_WARNING;
  73100. use const E_DEPRECATED;
  73101. use const E_ERROR;
  73102. use const E_NOTICE;
  73103. use const E_PARSE;
  73104. use const E_RECOVERABLE_ERROR;
  73105. use const E_STRICT;
  73106. use const E_USER_DEPRECATED;
  73107. use const E_USER_ERROR;
  73108. use const E_USER_NOTICE;
  73109. use const E_USER_WARNING;
  73110. use const E_WARNING;
  73111. use function defined;
  73112. use function error_reporting;
  73113. use function restore_error_handler;
  73114. use function set_error_handler;
  73115. use PHPUnit\Event;
  73116. use PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException;
  73117. use PHPUnit\Runner\Baseline\Baseline;
  73118. use PHPUnit\Runner\Baseline\Issue;
  73119. use PHPUnit\Util\ExcludeList;
  73120. /**
  73121. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73122. *
  73123. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73124. */
  73125. final class ErrorHandler
  73126. {
  73127. private const UNHANDLEABLE_LEVELS = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING;
  73128. private const INSUPPRESSIBLE_LEVELS = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR;
  73129. private static ?self $instance = null;
  73130. private ?Baseline $baseline = null;
  73131. private bool $enabled = \false;
  73132. private ?int $originalErrorReportingLevel = null;
  73133. public static function instance(): self
  73134. {
  73135. return self::$instance ?? self::$instance = new self();
  73136. }
  73137. /**
  73138. * @throws NoTestCaseObjectOnCallStackException
  73139. */
  73140. public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine): bool
  73141. {
  73142. $suppressed = (error_reporting() & ~self::INSUPPRESSIBLE_LEVELS) === 0;
  73143. if ($suppressed && (new ExcludeList())->isExcluded($errorFile)) {
  73144. return \false;
  73145. }
  73146. /**
  73147. * E_STRICT is deprecated since PHP 8.4.
  73148. *
  73149. * @see https://github.com/sebastianbergmann/phpunit/issues/5956
  73150. */
  73151. if (defined('E_STRICT') && $errorNumber === @E_STRICT) {
  73152. $errorNumber = E_NOTICE;
  73153. }
  73154. $test = Event\Code\TestMethodBuilder::fromCallStack();
  73155. $ignoredByBaseline = $this->ignoredByBaseline($errorFile, $errorLine, $errorString);
  73156. $ignoredByTest = $test->metadata()->isIgnoreDeprecations()->isNotEmpty();
  73157. switch ($errorNumber) {
  73158. case E_NOTICE:
  73159. Event\Facade::emitter()->testTriggeredPhpNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
  73160. break;
  73161. case E_USER_NOTICE:
  73162. Event\Facade::emitter()->testTriggeredNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
  73163. break;
  73164. case E_WARNING:
  73165. Event\Facade::emitter()->testTriggeredPhpWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
  73166. break;
  73167. case E_USER_WARNING:
  73168. Event\Facade::emitter()->testTriggeredWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
  73169. break;
  73170. case E_DEPRECATED:
  73171. Event\Facade::emitter()->testTriggeredPhpDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest);
  73172. break;
  73173. case E_USER_DEPRECATED:
  73174. Event\Facade::emitter()->testTriggeredDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest);
  73175. break;
  73176. case E_USER_ERROR:
  73177. Event\Facade::emitter()->testTriggeredError($test, $errorString, $errorFile, $errorLine, $suppressed);
  73178. throw new \PHPUnit\Runner\ErrorException('E_USER_ERROR was triggered');
  73179. default:
  73180. return \false;
  73181. }
  73182. return \false;
  73183. }
  73184. public function enable(): void
  73185. {
  73186. if ($this->enabled) {
  73187. return;
  73188. }
  73189. $oldErrorHandler = set_error_handler($this);
  73190. if ($oldErrorHandler !== null) {
  73191. restore_error_handler();
  73192. return;
  73193. }
  73194. $this->enabled = \true;
  73195. $this->originalErrorReportingLevel = error_reporting();
  73196. error_reporting($this->originalErrorReportingLevel & self::UNHANDLEABLE_LEVELS);
  73197. }
  73198. public function disable(): void
  73199. {
  73200. if (!$this->enabled) {
  73201. return;
  73202. }
  73203. restore_error_handler();
  73204. error_reporting(error_reporting() | $this->originalErrorReportingLevel);
  73205. $this->enabled = \false;
  73206. $this->originalErrorReportingLevel = null;
  73207. }
  73208. public function use(Baseline $baseline): void
  73209. {
  73210. $this->baseline = $baseline;
  73211. }
  73212. /**
  73213. * @psalm-param non-empty-string $file
  73214. * @psalm-param positive-int $line
  73215. * @psalm-param non-empty-string $description
  73216. */
  73217. private function ignoredByBaseline(string $file, int $line, string $description): bool
  73218. {
  73219. if ($this->baseline === null) {
  73220. return \false;
  73221. }
  73222. return $this->baseline->has(Issue::from($file, $line, null, $description));
  73223. }
  73224. }
  73225. <?php
  73226. declare (strict_types=1);
  73227. /*
  73228. * This file is part of PHPUnit.
  73229. *
  73230. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73231. *
  73232. * For the full copyright and license information, please view the LICENSE
  73233. * file that was distributed with this source code.
  73234. */
  73235. namespace PHPUnit\Runner;
  73236. use function sprintf;
  73237. use RuntimeException;
  73238. /**
  73239. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73240. *
  73241. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73242. */
  73243. final class ClassCannotBeFoundException extends RuntimeException implements \PHPUnit\Runner\Exception
  73244. {
  73245. public function __construct(string $className, string $file)
  73246. {
  73247. parent::__construct(sprintf('Class %s cannot be found in %s', $className, $file));
  73248. }
  73249. }
  73250. <?php
  73251. declare (strict_types=1);
  73252. /*
  73253. * This file is part of PHPUnit.
  73254. *
  73255. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73256. *
  73257. * For the full copyright and license information, please view the LICENSE
  73258. * file that was distributed with this source code.
  73259. */
  73260. namespace PHPUnit\Runner;
  73261. use function sprintf;
  73262. use RuntimeException;
  73263. /**
  73264. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73265. *
  73266. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73267. */
  73268. final class ClassDoesNotExtendTestCaseException extends RuntimeException implements \PHPUnit\Runner\Exception
  73269. {
  73270. public function __construct(string $className, string $file)
  73271. {
  73272. parent::__construct(sprintf('Class %s declared in %s does not extend PHPUnit\Framework\TestCase', $className, $file));
  73273. }
  73274. }
  73275. <?php
  73276. declare (strict_types=1);
  73277. /*
  73278. * This file is part of PHPUnit.
  73279. *
  73280. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73281. *
  73282. * For the full copyright and license information, please view the LICENSE
  73283. * file that was distributed with this source code.
  73284. */
  73285. namespace PHPUnit\Runner;
  73286. use function sprintf;
  73287. use RuntimeException;
  73288. /**
  73289. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73290. *
  73291. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73292. */
  73293. final class ClassIsAbstractException extends RuntimeException implements \PHPUnit\Runner\Exception
  73294. {
  73295. public function __construct(string $className, string $file)
  73296. {
  73297. parent::__construct(sprintf('Class %s declared in %s is abstract', $className, $file));
  73298. }
  73299. }
  73300. <?php
  73301. declare (strict_types=1);
  73302. /*
  73303. * This file is part of PHPUnit.
  73304. *
  73305. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73306. *
  73307. * For the full copyright and license information, please view the LICENSE
  73308. * file that was distributed with this source code.
  73309. */
  73310. namespace PHPUnit\Runner;
  73311. use function sprintf;
  73312. use RuntimeException;
  73313. /**
  73314. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73315. *
  73316. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73317. */
  73318. final class DirectoryDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
  73319. {
  73320. public function __construct(string $directory)
  73321. {
  73322. parent::__construct(sprintf('Directory "%s" does not exist and could not be created', $directory));
  73323. }
  73324. }
  73325. <?php
  73326. declare (strict_types=1);
  73327. /*
  73328. * This file is part of PHPUnit.
  73329. *
  73330. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73331. *
  73332. * For the full copyright and license information, please view the LICENSE
  73333. * file that was distributed with this source code.
  73334. */
  73335. namespace PHPUnit\Runner;
  73336. use Error;
  73337. /**
  73338. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73339. *
  73340. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73341. */
  73342. final class ErrorException extends Error implements \PHPUnit\Runner\Exception
  73343. {
  73344. }
  73345. <?php
  73346. declare (strict_types=1);
  73347. /*
  73348. * This file is part of PHPUnit.
  73349. *
  73350. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73351. *
  73352. * For the full copyright and license information, please view the LICENSE
  73353. * file that was distributed with this source code.
  73354. */
  73355. namespace PHPUnit\Runner;
  73356. /**
  73357. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73358. *
  73359. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73360. */
  73361. interface Exception extends \PHPUnit\Exception
  73362. {
  73363. }
  73364. <?php
  73365. declare (strict_types=1);
  73366. /*
  73367. * This file is part of PHPUnit.
  73368. *
  73369. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73370. *
  73371. * For the full copyright and license information, please view the LICENSE
  73372. * file that was distributed with this source code.
  73373. */
  73374. namespace PHPUnit\Runner;
  73375. use function sprintf;
  73376. use RuntimeException;
  73377. /**
  73378. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73379. *
  73380. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73381. */
  73382. final class FileDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
  73383. {
  73384. public function __construct(string $file)
  73385. {
  73386. parent::__construct(sprintf('File "%s" does not exist', $file));
  73387. }
  73388. }
  73389. <?php
  73390. declare (strict_types=1);
  73391. /*
  73392. * This file is part of PHPUnit.
  73393. *
  73394. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73395. *
  73396. * For the full copyright and license information, please view the LICENSE
  73397. * file that was distributed with this source code.
  73398. */
  73399. namespace PHPUnit\Runner;
  73400. use RuntimeException;
  73401. /**
  73402. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73403. *
  73404. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73405. */
  73406. final class InvalidOrderException extends RuntimeException implements \PHPUnit\Runner\Exception
  73407. {
  73408. }
  73409. <?php
  73410. declare (strict_types=1);
  73411. /*
  73412. * This file is part of PHPUnit.
  73413. *
  73414. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73415. *
  73416. * For the full copyright and license information, please view the LICENSE
  73417. * file that was distributed with this source code.
  73418. */
  73419. namespace PHPUnit\Runner;
  73420. use RuntimeException;
  73421. /**
  73422. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73423. *
  73424. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73425. */
  73426. final class InvalidPhptFileException extends RuntimeException implements \PHPUnit\Runner\Exception
  73427. {
  73428. }
  73429. <?php
  73430. declare (strict_types=1);
  73431. /*
  73432. * This file is part of PHPUnit.
  73433. *
  73434. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73435. *
  73436. * For the full copyright and license information, please view the LICENSE
  73437. * file that was distributed with this source code.
  73438. */
  73439. namespace PHPUnit\Runner;
  73440. use function sprintf;
  73441. use RuntimeException;
  73442. /**
  73443. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73444. *
  73445. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73446. */
  73447. final class ParameterDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
  73448. {
  73449. public function __construct(string $name)
  73450. {
  73451. parent::__construct(sprintf('Parameter "%s" does not exist', $name));
  73452. }
  73453. }
  73454. <?php
  73455. declare (strict_types=1);
  73456. /*
  73457. * This file is part of PHPUnit.
  73458. *
  73459. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73460. *
  73461. * For the full copyright and license information, please view the LICENSE
  73462. * file that was distributed with this source code.
  73463. */
  73464. namespace PHPUnit\Runner;
  73465. use function sprintf;
  73466. use RuntimeException;
  73467. /**
  73468. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73469. *
  73470. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73471. */
  73472. final class PhptExternalFileCannotBeLoadedException extends RuntimeException implements \PHPUnit\Runner\Exception
  73473. {
  73474. public function __construct(string $section, string $file)
  73475. {
  73476. parent::__construct(sprintf('Could not load --%s-- %s for PHPT file', $section . '_EXTERNAL', $file));
  73477. }
  73478. }
  73479. <?php
  73480. declare (strict_types=1);
  73481. /*
  73482. * This file is part of PHPUnit.
  73483. *
  73484. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73485. *
  73486. * For the full copyright and license information, please view the LICENSE
  73487. * file that was distributed with this source code.
  73488. */
  73489. namespace PHPUnit\Runner;
  73490. use function sprintf;
  73491. use RuntimeException;
  73492. /**
  73493. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73494. *
  73495. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73496. */
  73497. final class UnsupportedPhptSectionException extends RuntimeException implements \PHPUnit\Runner\Exception
  73498. {
  73499. public function __construct(string $section)
  73500. {
  73501. parent::__construct(sprintf('PHPUnit does not support PHPT %s sections', $section));
  73502. }
  73503. }
  73504. <?php
  73505. declare (strict_types=1);
  73506. /*
  73507. * This file is part of PHPUnit.
  73508. *
  73509. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73510. *
  73511. * For the full copyright and license information, please view the LICENSE
  73512. * file that was distributed with this source code.
  73513. */
  73514. namespace PHPUnit\Runner\Extension;
  73515. use PHPUnit\TextUI\Configuration\Configuration;
  73516. /**
  73517. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73518. */
  73519. interface Extension
  73520. {
  73521. public function bootstrap(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade, \PHPUnit\Runner\Extension\ParameterCollection $parameters): void;
  73522. }
  73523. <?php
  73524. declare (strict_types=1);
  73525. /*
  73526. * This file is part of PHPUnit.
  73527. *
  73528. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73529. *
  73530. * For the full copyright and license information, please view the LICENSE
  73531. * file that was distributed with this source code.
  73532. */
  73533. namespace PHPUnit\Runner\Extension;
  73534. use const PHP_EOL;
  73535. use function assert;
  73536. use function class_exists;
  73537. use function class_implements;
  73538. use function in_array;
  73539. use function sprintf;
  73540. use PHPUnit\Event\Facade as EventFacade;
  73541. use PHPUnit\TextUI\Configuration\Configuration;
  73542. use ReflectionClass;
  73543. use Throwable;
  73544. /**
  73545. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73546. *
  73547. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73548. */
  73549. final class ExtensionBootstrapper
  73550. {
  73551. private readonly Configuration $configuration;
  73552. private readonly \PHPUnit\Runner\Extension\Facade $facade;
  73553. public function __construct(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade)
  73554. {
  73555. $this->configuration = $configuration;
  73556. $this->facade = $facade;
  73557. }
  73558. /**
  73559. * @psalm-param class-string $className
  73560. * @psalm-param array<string, string> $parameters
  73561. */
  73562. public function bootstrap(string $className, array $parameters): void
  73563. {
  73564. if (!class_exists($className)) {
  73565. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot bootstrap extension because class %s does not exist', $className));
  73566. return;
  73567. }
  73568. if (!in_array(\PHPUnit\Runner\Extension\Extension::class, class_implements($className), \true)) {
  73569. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot bootstrap extension because class %s does not implement interface %s', $className, \PHPUnit\Runner\Extension\Extension::class));
  73570. return;
  73571. }
  73572. try {
  73573. $instance = (new ReflectionClass($className))->newInstance();
  73574. assert($instance instanceof \PHPUnit\Runner\Extension\Extension);
  73575. $instance->bootstrap($this->configuration, $this->facade, \PHPUnit\Runner\Extension\ParameterCollection::fromArray($parameters));
  73576. } catch (Throwable $t) {
  73577. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Bootstrapping of extension %s failed: %s%s%s', $className, $t->getMessage(), PHP_EOL, $t->getTraceAsString()));
  73578. return;
  73579. }
  73580. EventFacade::emitter()->testRunnerBootstrappedExtension($className, $parameters);
  73581. }
  73582. }
  73583. <?php
  73584. declare (strict_types=1);
  73585. /*
  73586. * This file is part of PHPUnit.
  73587. *
  73588. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73589. *
  73590. * For the full copyright and license information, please view the LICENSE
  73591. * file that was distributed with this source code.
  73592. */
  73593. namespace PHPUnit\Runner\Extension;
  73594. use PHPUnit\Event\EventFacadeIsSealedException;
  73595. use PHPUnit\Event\Facade as EventFacade;
  73596. use PHPUnit\Event\Subscriber;
  73597. use PHPUnit\Event\Tracer\Tracer;
  73598. use PHPUnit\Event\UnknownSubscriberTypeException;
  73599. /**
  73600. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73601. */
  73602. final class Facade
  73603. {
  73604. private bool $replacesOutput = \false;
  73605. private bool $replacesProgressOutput = \false;
  73606. private bool $replacesResultOutput = \false;
  73607. private bool $requiresCodeCoverageCollection = \false;
  73608. private bool $requiresExportOfObjects = \false;
  73609. /**
  73610. * @throws EventFacadeIsSealedException
  73611. * @throws UnknownSubscriberTypeException
  73612. */
  73613. public function registerSubscribers(Subscriber ...$subscribers): void
  73614. {
  73615. EventFacade::instance()->registerSubscribers(...$subscribers);
  73616. }
  73617. /**
  73618. * @throws EventFacadeIsSealedException
  73619. * @throws UnknownSubscriberTypeException
  73620. */
  73621. public function registerSubscriber(Subscriber $subscriber): void
  73622. {
  73623. EventFacade::instance()->registerSubscriber($subscriber);
  73624. }
  73625. /**
  73626. * @throws EventFacadeIsSealedException
  73627. */
  73628. public function registerTracer(Tracer $tracer): void
  73629. {
  73630. EventFacade::instance()->registerTracer($tracer);
  73631. }
  73632. public function replaceOutput(): void
  73633. {
  73634. $this->replacesOutput = \true;
  73635. }
  73636. public function replacesOutput(): bool
  73637. {
  73638. return $this->replacesOutput;
  73639. }
  73640. public function replaceProgressOutput(): void
  73641. {
  73642. $this->replacesProgressOutput = \true;
  73643. }
  73644. public function replacesProgressOutput(): bool
  73645. {
  73646. return $this->replacesOutput || $this->replacesProgressOutput;
  73647. }
  73648. public function replaceResultOutput(): void
  73649. {
  73650. $this->replacesResultOutput = \true;
  73651. }
  73652. public function replacesResultOutput(): bool
  73653. {
  73654. return $this->replacesOutput || $this->replacesResultOutput;
  73655. }
  73656. public function requireCodeCoverageCollection(): void
  73657. {
  73658. $this->requiresCodeCoverageCollection = \true;
  73659. }
  73660. public function requiresCodeCoverageCollection(): bool
  73661. {
  73662. return $this->requiresCodeCoverageCollection;
  73663. }
  73664. /**
  73665. * @deprecated
  73666. */
  73667. public function requireExportOfObjects(): void
  73668. {
  73669. $this->requiresExportOfObjects = \true;
  73670. }
  73671. /**
  73672. * @deprecated
  73673. */
  73674. public function requiresExportOfObjects(): bool
  73675. {
  73676. return $this->requiresExportOfObjects;
  73677. }
  73678. }
  73679. <?php
  73680. declare (strict_types=1);
  73681. /*
  73682. * This file is part of PHPUnit.
  73683. *
  73684. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73685. *
  73686. * For the full copyright and license information, please view the LICENSE
  73687. * file that was distributed with this source code.
  73688. */
  73689. namespace PHPUnit\Runner\Extension;
  73690. use function array_key_exists;
  73691. use PHPUnit\Runner\ParameterDoesNotExistException;
  73692. /**
  73693. * @psalm-immutable
  73694. *
  73695. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73696. */
  73697. final class ParameterCollection
  73698. {
  73699. private readonly array $parameters;
  73700. /**
  73701. * @psalm-param array<string, string> $parameters
  73702. */
  73703. public static function fromArray(array $parameters): self
  73704. {
  73705. return new self($parameters);
  73706. }
  73707. private function __construct(array $parameters)
  73708. {
  73709. $this->parameters = $parameters;
  73710. }
  73711. public function has(string $name): bool
  73712. {
  73713. return array_key_exists($name, $this->parameters);
  73714. }
  73715. /**
  73716. * @throws ParameterDoesNotExistException
  73717. */
  73718. public function get(string $name): string
  73719. {
  73720. if (!$this->has($name)) {
  73721. throw new ParameterDoesNotExistException($name);
  73722. }
  73723. return $this->parameters[$name];
  73724. }
  73725. }
  73726. <?php
  73727. declare (strict_types=1);
  73728. /*
  73729. * This file is part of PHPUnit.
  73730. *
  73731. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73732. *
  73733. * For the full copyright and license information, please view the LICENSE
  73734. * file that was distributed with this source code.
  73735. */
  73736. namespace PHPUnit\Runner\Extension;
  73737. use function count;
  73738. use function explode;
  73739. use function extension_loaded;
  73740. use function implode;
  73741. use function is_file;
  73742. use function sprintf;
  73743. use function str_contains;
  73744. use PHPUnitPHAR\PharIo\Manifest\ApplicationName;
  73745. use PHPUnitPHAR\PharIo\Manifest\Exception as ManifestException;
  73746. use PHPUnitPHAR\PharIo\Manifest\ManifestLoader;
  73747. use PHPUnitPHAR\PharIo\Version\Version as PharIoVersion;
  73748. use PHPUnit\Event;
  73749. use PHPUnit\Runner\Version;
  73750. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  73751. use Throwable;
  73752. /**
  73753. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73754. *
  73755. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73756. */
  73757. final class PharLoader
  73758. {
  73759. /**
  73760. * @psalm-param non-empty-string $directory
  73761. *
  73762. * @psalm-return list<string>
  73763. */
  73764. public function loadPharExtensionsInDirectory(string $directory): array
  73765. {
  73766. $pharExtensionLoaded = extension_loaded('phar');
  73767. $loadedExtensions = [];
  73768. foreach ((new FileIteratorFacade())->getFilesAsArray($directory, '.phar') as $file) {
  73769. if (!$pharExtensionLoaded) {
  73770. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s because the PHAR extension is not available', $file));
  73771. continue;
  73772. }
  73773. if (!is_file('phar://' . $file . '/manifest.xml')) {
  73774. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not an extension for PHPUnit', $file));
  73775. continue;
  73776. }
  73777. try {
  73778. $applicationName = new ApplicationName('phpunit/phpunit');
  73779. $version = new PharIoVersion($this->phpunitVersion());
  73780. $manifest = ManifestLoader::fromFile('phar://' . $file . '/manifest.xml');
  73781. if (!$manifest->isExtensionFor($applicationName)) {
  73782. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not an extension for PHPUnit', $file));
  73783. continue;
  73784. }
  73785. if (!$manifest->isExtensionFor($applicationName, $version)) {
  73786. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not compatible with PHPUnit %s', $file, Version::series()));
  73787. continue;
  73788. }
  73789. } catch (ManifestException $e) {
  73790. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s: %s', $file, $e->getMessage()));
  73791. continue;
  73792. }
  73793. try {
  73794. /** @psalm-suppress UnresolvableInclude */
  73795. @require $file;
  73796. } catch (Throwable $t) {
  73797. Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s: %s', $file, $t->getMessage()));
  73798. continue;
  73799. }
  73800. $loadedExtensions[] = $manifest->getName()->asString() . ' ' . $manifest->getVersion()->getVersionString();
  73801. Event\Facade::emitter()->testRunnerLoadedExtensionFromPhar($file, $manifest->getName()->asString(), $manifest->getVersion()->getVersionString());
  73802. }
  73803. return $loadedExtensions;
  73804. }
  73805. private function phpunitVersion(): string
  73806. {
  73807. $version = Version::id();
  73808. if (!str_contains($version, '-')) {
  73809. return $version;
  73810. }
  73811. $parts = explode('.', explode('-', $version)[0]);
  73812. if (count($parts) === 2) {
  73813. $parts[] = 0;
  73814. }
  73815. return implode('.', $parts);
  73816. }
  73817. }
  73818. <?php
  73819. declare (strict_types=1);
  73820. /*
  73821. * This file is part of PHPUnit.
  73822. *
  73823. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73824. *
  73825. * For the full copyright and license information, please view the LICENSE
  73826. * file that was distributed with this source code.
  73827. */
  73828. namespace PHPUnit\Runner\Filter;
  73829. use function in_array;
  73830. /**
  73831. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73832. *
  73833. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73834. */
  73835. final class ExcludeGroupFilterIterator extends \PHPUnit\Runner\Filter\GroupFilterIterator
  73836. {
  73837. protected function doAccept(int $id): bool
  73838. {
  73839. return !in_array($id, $this->groupTests, \true);
  73840. }
  73841. }
  73842. <?php
  73843. declare (strict_types=1);
  73844. /*
  73845. * This file is part of PHPUnit.
  73846. *
  73847. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73848. *
  73849. * For the full copyright and license information, please view the LICENSE
  73850. * file that was distributed with this source code.
  73851. */
  73852. namespace PHPUnit\Runner\Filter;
  73853. use function assert;
  73854. use FilterIterator;
  73855. use Iterator;
  73856. use PHPUnit\Framework\TestSuite;
  73857. use ReflectionClass;
  73858. /**
  73859. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73860. *
  73861. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73862. */
  73863. final class Factory
  73864. {
  73865. /**
  73866. * @psalm-var array<int,array{0: ReflectionClass, 1: array|string}>
  73867. */
  73868. private array $filters = [];
  73869. /**
  73870. * @psalm-param list<non-empty-string> $testIds
  73871. */
  73872. public function addTestIdFilter(array $testIds): void
  73873. {
  73874. $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\TestIdFilterIterator::class), $testIds];
  73875. }
  73876. /**
  73877. * @psalm-param list<non-empty-string> $groups
  73878. */
  73879. public function addExcludeGroupFilter(array $groups): void
  73880. {
  73881. $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\ExcludeGroupFilterIterator::class), $groups];
  73882. }
  73883. /**
  73884. * @psalm-param list<non-empty-string> $groups
  73885. */
  73886. public function addIncludeGroupFilter(array $groups): void
  73887. {
  73888. $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\IncludeGroupFilterIterator::class), $groups];
  73889. }
  73890. /**
  73891. * @psalm-param non-empty-string $name
  73892. */
  73893. public function addNameFilter(string $name): void
  73894. {
  73895. $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\NameFilterIterator::class), $name];
  73896. }
  73897. public function factory(Iterator $iterator, TestSuite $suite): FilterIterator
  73898. {
  73899. foreach ($this->filters as $filter) {
  73900. [$class, $arguments] = $filter;
  73901. $iterator = $class->newInstance($iterator, $arguments, $suite);
  73902. }
  73903. assert($iterator instanceof FilterIterator);
  73904. return $iterator;
  73905. }
  73906. }
  73907. <?php
  73908. declare (strict_types=1);
  73909. /*
  73910. * This file is part of PHPUnit.
  73911. *
  73912. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73913. *
  73914. * For the full copyright and license information, please view the LICENSE
  73915. * file that was distributed with this source code.
  73916. */
  73917. namespace PHPUnit\Runner\Filter;
  73918. use function array_map;
  73919. use function array_push;
  73920. use function in_array;
  73921. use function spl_object_id;
  73922. use PHPUnit\Framework\Test;
  73923. use PHPUnit\Framework\TestSuite;
  73924. use RecursiveFilterIterator;
  73925. use RecursiveIterator;
  73926. /**
  73927. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73928. *
  73929. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73930. */
  73931. abstract class GroupFilterIterator extends RecursiveFilterIterator
  73932. {
  73933. /**
  73934. * @psalm-var list<int>
  73935. */
  73936. protected array $groupTests = [];
  73937. /**
  73938. * @psalm-param RecursiveIterator<int, Test> $iterator
  73939. * @psalm-param list<non-empty-string> $groups
  73940. */
  73941. public function __construct(RecursiveIterator $iterator, array $groups, TestSuite $suite)
  73942. {
  73943. parent::__construct($iterator);
  73944. foreach ($suite->groupDetails() as $group => $tests) {
  73945. if (in_array((string) $group, $groups, \true)) {
  73946. $testHashes = array_map('spl_object_id', $tests);
  73947. array_push($this->groupTests, ...$testHashes);
  73948. }
  73949. }
  73950. }
  73951. public function accept(): bool
  73952. {
  73953. $test = $this->getInnerIterator()->current();
  73954. if ($test instanceof TestSuite) {
  73955. return \true;
  73956. }
  73957. return $this->doAccept(spl_object_id($test));
  73958. }
  73959. abstract protected function doAccept(int $id): bool;
  73960. }
  73961. <?php
  73962. declare (strict_types=1);
  73963. /*
  73964. * This file is part of PHPUnit.
  73965. *
  73966. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73967. *
  73968. * For the full copyright and license information, please view the LICENSE
  73969. * file that was distributed with this source code.
  73970. */
  73971. namespace PHPUnit\Runner\Filter;
  73972. use function in_array;
  73973. /**
  73974. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  73975. *
  73976. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  73977. */
  73978. final class IncludeGroupFilterIterator extends \PHPUnit\Runner\Filter\GroupFilterIterator
  73979. {
  73980. protected function doAccept(int $id): bool
  73981. {
  73982. return in_array($id, $this->groupTests, \true);
  73983. }
  73984. }
  73985. <?php
  73986. declare (strict_types=1);
  73987. /*
  73988. * This file is part of PHPUnit.
  73989. *
  73990. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  73991. *
  73992. * For the full copyright and license information, please view the LICENSE
  73993. * file that was distributed with this source code.
  73994. */
  73995. namespace PHPUnit\Runner\Filter;
  73996. use function end;
  73997. use function implode;
  73998. use function preg_match;
  73999. use function sprintf;
  74000. use function str_replace;
  74001. use function substr;
  74002. use Exception;
  74003. use PHPUnit\Framework\SelfDescribing;
  74004. use PHPUnit\Framework\Test;
  74005. use PHPUnit\Framework\TestCase;
  74006. use PHPUnit\Framework\TestSuite;
  74007. use RecursiveFilterIterator;
  74008. use RecursiveIterator;
  74009. /**
  74010. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74011. *
  74012. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74013. */
  74014. final class NameFilterIterator extends RecursiveFilterIterator
  74015. {
  74016. private ?string $filter = null;
  74017. private ?int $filterMin = null;
  74018. private ?int $filterMax = null;
  74019. /**
  74020. * @psalm-param RecursiveIterator<int, Test> $iterator
  74021. * @psalm-param non-empty-string $filter
  74022. *
  74023. * @throws Exception
  74024. */
  74025. public function __construct(RecursiveIterator $iterator, string $filter)
  74026. {
  74027. parent::__construct($iterator);
  74028. $this->setFilter($filter);
  74029. }
  74030. public function accept(): bool
  74031. {
  74032. $test = $this->getInnerIterator()->current();
  74033. if ($test instanceof TestSuite) {
  74034. return \true;
  74035. }
  74036. $tmp = $this->describe($test);
  74037. if ($tmp[0] !== '') {
  74038. $name = implode('::', $tmp);
  74039. } else {
  74040. $name = $tmp[1];
  74041. }
  74042. $accepted = @preg_match($this->filter, $name, $matches);
  74043. if ($accepted && isset($this->filterMax)) {
  74044. $set = end($matches);
  74045. $accepted = $set >= $this->filterMin && $set <= $this->filterMax;
  74046. }
  74047. return (bool) $accepted;
  74048. }
  74049. /**
  74050. * @throws Exception
  74051. */
  74052. private function setFilter(string $filter): void
  74053. {
  74054. if (preg_match('/[a-zA-Z0-9]/', substr($filter, 0, 1)) === 1 || @preg_match($filter, '') === \false) {
  74055. // Handles:
  74056. // * testAssertEqualsSucceeds#4
  74057. // * testAssertEqualsSucceeds#4-8
  74058. if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
  74059. if (isset($matches[3]) && $matches[2] < $matches[3]) {
  74060. $filter = sprintf('%s.*with data set #(\d+)$', $matches[1]);
  74061. $this->filterMin = (int) $matches[2];
  74062. $this->filterMax = (int) $matches[3];
  74063. } else {
  74064. $filter = sprintf('%s.*with data set #%s$', $matches[1], $matches[2]);
  74065. }
  74066. } elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
  74067. $filter = sprintf('%s.*with data set "%s"$', $matches[1], $matches[2]);
  74068. }
  74069. // Escape delimiters in regular expression. Do NOT use preg_quote,
  74070. // to keep magic characters.
  74071. $filter = sprintf('/%s/i', str_replace('/', '\/', $filter));
  74072. }
  74073. $this->filter = $filter;
  74074. }
  74075. /**
  74076. * @psalm-return array{0: string, 1: string}
  74077. */
  74078. private function describe(Test $test): array
  74079. {
  74080. if ($test instanceof TestCase) {
  74081. return [$test::class, $test->nameWithDataSet()];
  74082. }
  74083. if ($test instanceof SelfDescribing) {
  74084. return ['', $test->toString()];
  74085. }
  74086. return ['', $test::class];
  74087. }
  74088. }
  74089. <?php
  74090. declare (strict_types=1);
  74091. /*
  74092. * This file is part of PHPUnit.
  74093. *
  74094. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74095. *
  74096. * For the full copyright and license information, please view the LICENSE
  74097. * file that was distributed with this source code.
  74098. */
  74099. namespace PHPUnit\Runner\Filter;
  74100. use function in_array;
  74101. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  74102. use PHPUnit\Event\TestData\NoDataSetFromDataProviderException;
  74103. use PHPUnit\Framework\Test;
  74104. use PHPUnit\Framework\TestCase;
  74105. use PHPUnit\Framework\TestSuite;
  74106. use PHPUnit\Runner\PhptTestCase;
  74107. use RecursiveFilterIterator;
  74108. use RecursiveIterator;
  74109. /**
  74110. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74111. *
  74112. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74113. */
  74114. final class TestIdFilterIterator extends RecursiveFilterIterator
  74115. {
  74116. /**
  74117. * @psalm-var non-empty-list<non-empty-string>
  74118. */
  74119. private readonly array $testIds;
  74120. /**
  74121. * @psalm-param RecursiveIterator<int, Test> $iterator
  74122. * @psalm-param non-empty-list<non-empty-string> $testIds
  74123. */
  74124. public function __construct(RecursiveIterator $iterator, array $testIds)
  74125. {
  74126. parent::__construct($iterator);
  74127. $this->testIds = $testIds;
  74128. }
  74129. public function accept(): bool
  74130. {
  74131. $test = $this->getInnerIterator()->current();
  74132. if ($test instanceof TestSuite) {
  74133. return \true;
  74134. }
  74135. if (!$test instanceof TestCase && !$test instanceof PhptTestCase) {
  74136. return \false;
  74137. }
  74138. try {
  74139. return in_array($test->valueObjectForEvents()->id(), $this->testIds, \true);
  74140. } catch (MoreThanOneDataSetFromDataProviderException|NoDataSetFromDataProviderException) {
  74141. return \false;
  74142. }
  74143. }
  74144. }
  74145. <?php
  74146. declare (strict_types=1);
  74147. /*
  74148. * This file is part of PHPUnit.
  74149. *
  74150. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74151. *
  74152. * For the full copyright and license information, please view the LICENSE
  74153. * file that was distributed with this source code.
  74154. */
  74155. namespace PHPUnit\Runner\GarbageCollection;
  74156. use function gc_collect_cycles;
  74157. use function gc_disable;
  74158. use function gc_enable;
  74159. use PHPUnit\Event\EventFacadeIsSealedException;
  74160. use PHPUnit\Event\Facade;
  74161. use PHPUnit\Event\UnknownSubscriberTypeException;
  74162. /**
  74163. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74164. *
  74165. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74166. */
  74167. final class GarbageCollectionHandler
  74168. {
  74169. private readonly Facade $facade;
  74170. private readonly int $threshold;
  74171. private int $tests = 0;
  74172. /**
  74173. * @throws EventFacadeIsSealedException
  74174. * @throws UnknownSubscriberTypeException
  74175. */
  74176. public function __construct(Facade $facade, int $threshold)
  74177. {
  74178. $this->facade = $facade;
  74179. $this->threshold = $threshold;
  74180. $this->registerSubscribers();
  74181. }
  74182. public function executionStarted(): void
  74183. {
  74184. gc_disable();
  74185. $this->facade->emitter()->testRunnerDisabledGarbageCollection();
  74186. gc_collect_cycles();
  74187. $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
  74188. }
  74189. public function executionFinished(): void
  74190. {
  74191. gc_collect_cycles();
  74192. $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
  74193. gc_enable();
  74194. $this->facade->emitter()->testRunnerEnabledGarbageCollection();
  74195. }
  74196. public function testFinished(): void
  74197. {
  74198. $this->tests++;
  74199. if ($this->tests === $this->threshold) {
  74200. gc_collect_cycles();
  74201. $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
  74202. $this->tests = 0;
  74203. }
  74204. }
  74205. /**
  74206. * @throws EventFacadeIsSealedException
  74207. * @throws UnknownSubscriberTypeException
  74208. */
  74209. private function registerSubscribers(): void
  74210. {
  74211. $this->facade->registerSubscribers(new \PHPUnit\Runner\GarbageCollection\ExecutionStartedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\ExecutionFinishedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\TestFinishedSubscriber($this));
  74212. }
  74213. }
  74214. <?php
  74215. declare (strict_types=1);
  74216. /*
  74217. * This file is part of PHPUnit.
  74218. *
  74219. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74220. *
  74221. * For the full copyright and license information, please view the LICENSE
  74222. * file that was distributed with this source code.
  74223. */
  74224. namespace PHPUnit\Runner\GarbageCollection;
  74225. use PHPUnit\Event\InvalidArgumentException;
  74226. use PHPUnit\Event\TestRunner\ExecutionFinished;
  74227. use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber as TestRunnerExecutionFinishedSubscriber;
  74228. /**
  74229. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74230. *
  74231. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74232. */
  74233. final class ExecutionFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionFinishedSubscriber
  74234. {
  74235. /**
  74236. * @throws \PHPUnit\Framework\InvalidArgumentException
  74237. * @throws InvalidArgumentException
  74238. */
  74239. public function notify(ExecutionFinished $event): void
  74240. {
  74241. $this->handler()->executionFinished();
  74242. }
  74243. }
  74244. <?php
  74245. declare (strict_types=1);
  74246. /*
  74247. * This file is part of PHPUnit.
  74248. *
  74249. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74250. *
  74251. * For the full copyright and license information, please view the LICENSE
  74252. * file that was distributed with this source code.
  74253. */
  74254. namespace PHPUnit\Runner\GarbageCollection;
  74255. use PHPUnit\Event\InvalidArgumentException;
  74256. use PHPUnit\Event\TestRunner\ExecutionStarted;
  74257. use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber as TestRunnerExecutionStartedSubscriber;
  74258. /**
  74259. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74260. *
  74261. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74262. */
  74263. final class ExecutionStartedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionStartedSubscriber
  74264. {
  74265. /**
  74266. * @throws \PHPUnit\Framework\InvalidArgumentException
  74267. * @throws InvalidArgumentException
  74268. */
  74269. public function notify(ExecutionStarted $event): void
  74270. {
  74271. $this->handler()->executionStarted();
  74272. }
  74273. }
  74274. <?php
  74275. declare (strict_types=1);
  74276. /*
  74277. * This file is part of PHPUnit.
  74278. *
  74279. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74280. *
  74281. * For the full copyright and license information, please view the LICENSE
  74282. * file that was distributed with this source code.
  74283. */
  74284. namespace PHPUnit\Runner\GarbageCollection;
  74285. /**
  74286. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74287. *
  74288. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74289. */
  74290. abstract class Subscriber
  74291. {
  74292. private readonly \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler;
  74293. public function __construct(\PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler)
  74294. {
  74295. $this->handler = $handler;
  74296. }
  74297. protected function handler(): \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler
  74298. {
  74299. return $this->handler;
  74300. }
  74301. }
  74302. <?php
  74303. declare (strict_types=1);
  74304. /*
  74305. * This file is part of PHPUnit.
  74306. *
  74307. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74308. *
  74309. * For the full copyright and license information, please view the LICENSE
  74310. * file that was distributed with this source code.
  74311. */
  74312. namespace PHPUnit\Runner\GarbageCollection;
  74313. use PHPUnit\Event\InvalidArgumentException;
  74314. use PHPUnit\Event\Test\Finished;
  74315. use PHPUnit\Event\Test\FinishedSubscriber;
  74316. /**
  74317. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74318. *
  74319. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74320. */
  74321. final class TestFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements FinishedSubscriber
  74322. {
  74323. /**
  74324. * @throws \PHPUnit\Framework\InvalidArgumentException
  74325. * @throws InvalidArgumentException
  74326. */
  74327. public function notify(Finished $event): void
  74328. {
  74329. $this->handler()->testFinished();
  74330. }
  74331. }
  74332. <?php
  74333. declare (strict_types=1);
  74334. /*
  74335. * This file is part of PHPUnit.
  74336. *
  74337. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74338. *
  74339. * For the full copyright and license information, please view the LICENSE
  74340. * file that was distributed with this source code.
  74341. */
  74342. namespace PHPUnit\Runner;
  74343. use const DEBUG_BACKTRACE_IGNORE_ARGS;
  74344. use const DIRECTORY_SEPARATOR;
  74345. use function array_merge;
  74346. use function basename;
  74347. use function debug_backtrace;
  74348. use function defined;
  74349. use function dirname;
  74350. use function explode;
  74351. use function extension_loaded;
  74352. use function file;
  74353. use function file_get_contents;
  74354. use function file_put_contents;
  74355. use function is_array;
  74356. use function is_file;
  74357. use function is_readable;
  74358. use function is_string;
  74359. use function ltrim;
  74360. use function preg_match;
  74361. use function preg_replace;
  74362. use function preg_split;
  74363. use function realpath;
  74364. use function rtrim;
  74365. use function str_contains;
  74366. use function str_replace;
  74367. use function str_starts_with;
  74368. use function strncasecmp;
  74369. use function substr;
  74370. use function trim;
  74371. use function unlink;
  74372. use function unserialize;
  74373. use function var_export;
  74374. use PHPUnit\Event\Code\Phpt;
  74375. use PHPUnit\Event\Code\ThrowableBuilder;
  74376. use PHPUnit\Event\Facade as EventFacade;
  74377. use PHPUnit\Event\NoPreviousThrowableException;
  74378. use PHPUnit\Framework\Assert;
  74379. use PHPUnit\Framework\AssertionFailedError;
  74380. use PHPUnit\Framework\ExecutionOrderDependency;
  74381. use PHPUnit\Framework\ExpectationFailedException;
  74382. use PHPUnit\Framework\IncompleteTestError;
  74383. use PHPUnit\Framework\PhptAssertionFailedError;
  74384. use PHPUnit\Framework\Reorderable;
  74385. use PHPUnit\Framework\SelfDescribing;
  74386. use PHPUnit\Framework\Test;
  74387. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  74388. use PHPUnit\Util\PHP\AbstractPhpProcess;
  74389. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
  74390. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
  74391. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ReflectionException;
  74392. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
  74393. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
  74394. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\TestIdMissingException;
  74395. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
  74396. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  74397. use Throwable;
  74398. /**
  74399. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74400. *
  74401. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74402. */
  74403. final class PhptTestCase implements Reorderable, SelfDescribing, Test
  74404. {
  74405. /**
  74406. * @psalm-var non-empty-string
  74407. */
  74408. private readonly string $filename;
  74409. private readonly AbstractPhpProcess $phpUtil;
  74410. private string $output = '';
  74411. /**
  74412. * Constructs a test case with the given filename.
  74413. *
  74414. * @psalm-param non-empty-string $filename
  74415. *
  74416. * @throws Exception
  74417. */
  74418. public function __construct(string $filename, ?AbstractPhpProcess $phpUtil = null)
  74419. {
  74420. $this->filename = $filename;
  74421. $this->phpUtil = $phpUtil ?: AbstractPhpProcess::factory();
  74422. }
  74423. /**
  74424. * Counts the number of test cases executed by run(TestResult result).
  74425. */
  74426. public function count(): int
  74427. {
  74428. return 1;
  74429. }
  74430. /**
  74431. * Runs a test and collects its result in a TestResult instance.
  74432. *
  74433. * @throws \PHPUnit\Framework\Exception
  74434. * @throws \SebastianBergmann\Template\InvalidArgumentException
  74435. * @throws Exception
  74436. * @throws InvalidArgumentException
  74437. * @throws NoPreviousThrowableException
  74438. * @throws ReflectionException
  74439. * @throws TestIdMissingException
  74440. * @throws UnintentionallyCoveredCodeException
  74441. *
  74442. * @noinspection RepetitiveMethodCallsInspection
  74443. */
  74444. public function run(): void
  74445. {
  74446. $emitter = EventFacade::emitter();
  74447. $emitter->testPreparationStarted($this->valueObjectForEvents());
  74448. try {
  74449. $sections = $this->parse();
  74450. } catch (\PHPUnit\Runner\Exception $e) {
  74451. $emitter->testPrepared($this->valueObjectForEvents());
  74452. $emitter->testErrored($this->valueObjectForEvents(), ThrowableBuilder::from($e));
  74453. $emitter->testFinished($this->valueObjectForEvents(), 0);
  74454. return;
  74455. }
  74456. $code = $this->render($sections['FILE']);
  74457. $xfail = \false;
  74458. $settings = $this->parseIniSection($this->settings(\PHPUnit\Runner\CodeCoverage::instance()->isActive()));
  74459. $emitter->testPrepared($this->valueObjectForEvents());
  74460. if (isset($sections['INI'])) {
  74461. $settings = $this->parseIniSection($sections['INI'], $settings);
  74462. }
  74463. if (isset($sections['ENV'])) {
  74464. $env = $this->parseEnvSection($sections['ENV']);
  74465. $this->phpUtil->setEnv($env);
  74466. }
  74467. $this->phpUtil->setUseStderrRedirection(\true);
  74468. if ($this->shouldTestBeSkipped($sections, $settings)) {
  74469. return;
  74470. }
  74471. if (isset($sections['XFAIL'])) {
  74472. $xfail = trim($sections['XFAIL']);
  74473. }
  74474. if (isset($sections['STDIN'])) {
  74475. $this->phpUtil->setStdin($sections['STDIN']);
  74476. }
  74477. if (isset($sections['ARGS'])) {
  74478. $this->phpUtil->setArgs($sections['ARGS']);
  74479. }
  74480. if (\PHPUnit\Runner\CodeCoverage::instance()->isActive()) {
  74481. $codeCoverageCacheDirectory = null;
  74482. if (\PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->cachesStaticAnalysis()) {
  74483. /** @psalm-suppress MissingThrowsDocblock */
  74484. $codeCoverageCacheDirectory = \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->cacheDirectory();
  74485. }
  74486. $this->renderForCoverage($code, \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->collectsBranchAndPathCoverage(), $codeCoverageCacheDirectory);
  74487. }
  74488. $jobResult = $this->phpUtil->runJob($code, $this->stringifyIni($settings));
  74489. $this->output = $jobResult['stdout'] ?? '';
  74490. if (\PHPUnit\Runner\CodeCoverage::instance()->isActive()) {
  74491. $coverage = $this->cleanupForCoverage();
  74492. \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->start($this->filename, TestSize::large());
  74493. \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->append($coverage, $this->filename, \true, TestStatus::unknown());
  74494. }
  74495. $passed = \true;
  74496. try {
  74497. $this->assertPhptExpectation($sections, $this->output);
  74498. } catch (AssertionFailedError $e) {
  74499. $failure = $e;
  74500. if ($xfail !== \false) {
  74501. $failure = new IncompleteTestError($xfail, 0, $e);
  74502. } elseif ($e instanceof ExpectationFailedException) {
  74503. $comparisonFailure = $e->getComparisonFailure();
  74504. if ($comparisonFailure) {
  74505. $diff = $comparisonFailure->getDiff();
  74506. } else {
  74507. $diff = $e->getMessage();
  74508. }
  74509. $hint = $this->getLocationHintFromDiff($diff, $sections);
  74510. $trace = array_merge($hint, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
  74511. $failure = new PhptAssertionFailedError($e->getMessage(), 0, (string) $trace[0]['file'], (int) $trace[0]['line'], $trace, $comparisonFailure ? $diff : '');
  74512. }
  74513. if ($failure instanceof IncompleteTestError) {
  74514. $emitter->testMarkedAsIncomplete($this->valueObjectForEvents(), ThrowableBuilder::from($failure));
  74515. } else {
  74516. $emitter->testFailed($this->valueObjectForEvents(), ThrowableBuilder::from($failure), null);
  74517. }
  74518. $passed = \false;
  74519. } catch (Throwable $t) {
  74520. $emitter->testErrored($this->valueObjectForEvents(), ThrowableBuilder::from($t));
  74521. $passed = \false;
  74522. }
  74523. if ($passed) {
  74524. $emitter->testPassed($this->valueObjectForEvents());
  74525. }
  74526. $this->runClean($sections, \PHPUnit\Runner\CodeCoverage::instance()->isActive());
  74527. $emitter->testFinished($this->valueObjectForEvents(), 1);
  74528. }
  74529. /**
  74530. * Returns the name of the test case.
  74531. */
  74532. public function getName(): string
  74533. {
  74534. return $this->toString();
  74535. }
  74536. /**
  74537. * Returns a string representation of the test case.
  74538. */
  74539. public function toString(): string
  74540. {
  74541. return $this->filename;
  74542. }
  74543. public function usesDataProvider(): bool
  74544. {
  74545. return \false;
  74546. }
  74547. public function numberOfAssertionsPerformed(): int
  74548. {
  74549. return 1;
  74550. }
  74551. public function output(): string
  74552. {
  74553. return $this->output;
  74554. }
  74555. public function hasOutput(): bool
  74556. {
  74557. return !empty($this->output);
  74558. }
  74559. public function sortId(): string
  74560. {
  74561. return $this->filename;
  74562. }
  74563. /**
  74564. * @psalm-return list<ExecutionOrderDependency>
  74565. */
  74566. public function provides(): array
  74567. {
  74568. return [];
  74569. }
  74570. /**
  74571. * @psalm-return list<ExecutionOrderDependency>
  74572. */
  74573. public function requires(): array
  74574. {
  74575. return [];
  74576. }
  74577. /**
  74578. * @internal This method is not covered by the backward compatibility promise for PHPUnit
  74579. */
  74580. public function valueObjectForEvents(): Phpt
  74581. {
  74582. return new Phpt($this->filename);
  74583. }
  74584. /**
  74585. * Parse --INI-- section key value pairs and return as array.
  74586. */
  74587. private function parseIniSection(array|string $content, array $ini = []): array
  74588. {
  74589. if (is_string($content)) {
  74590. $content = explode("\n", trim($content));
  74591. }
  74592. foreach ($content as $setting) {
  74593. if (!str_contains($setting, '=')) {
  74594. continue;
  74595. }
  74596. $setting = explode('=', $setting, 2);
  74597. $name = trim($setting[0]);
  74598. $value = trim($setting[1]);
  74599. if ($name === 'extension' || $name === 'zend_extension') {
  74600. if (!isset($ini[$name])) {
  74601. $ini[$name] = [];
  74602. }
  74603. $ini[$name][] = $value;
  74604. continue;
  74605. }
  74606. $ini[$name] = $value;
  74607. }
  74608. return $ini;
  74609. }
  74610. private function parseEnvSection(string $content): array
  74611. {
  74612. $env = [];
  74613. foreach (explode("\n", trim($content)) as $e) {
  74614. $e = explode('=', trim($e), 2);
  74615. if ($e[0] !== '' && isset($e[1])) {
  74616. $env[$e[0]] = $e[1];
  74617. }
  74618. }
  74619. return $env;
  74620. }
  74621. /**
  74622. * @throws Exception
  74623. * @throws ExpectationFailedException
  74624. */
  74625. private function assertPhptExpectation(array $sections, string $output): void
  74626. {
  74627. $assertions = ['EXPECT' => 'assertEquals', 'EXPECTF' => 'assertStringMatchesFormat', 'EXPECTREGEX' => 'assertMatchesRegularExpression'];
  74628. $actual = preg_replace('/\r\n/', "\n", trim($output));
  74629. foreach ($assertions as $sectionName => $sectionAssertion) {
  74630. if (isset($sections[$sectionName])) {
  74631. $sectionContent = preg_replace('/\r\n/', "\n", trim($sections[$sectionName]));
  74632. $expected = $sectionName === 'EXPECTREGEX' ? "/{$sectionContent}/" : $sectionContent;
  74633. Assert::$sectionAssertion($expected, $actual);
  74634. return;
  74635. }
  74636. }
  74637. throw new \PHPUnit\Runner\InvalidPhptFileException();
  74638. }
  74639. private function shouldTestBeSkipped(array $sections, array $settings): bool
  74640. {
  74641. if (!isset($sections['SKIPIF'])) {
  74642. return \false;
  74643. }
  74644. $skipif = $this->render($sections['SKIPIF']);
  74645. $jobResult = $this->phpUtil->runJob($skipif, $this->stringifyIni($settings));
  74646. if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
  74647. $message = '';
  74648. if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $skipMatch)) {
  74649. $message = substr($skipMatch[1], 2);
  74650. }
  74651. EventFacade::emitter()->testSkipped($this->valueObjectForEvents(), $message);
  74652. EventFacade::emitter()->testFinished($this->valueObjectForEvents(), 0);
  74653. return \true;
  74654. }
  74655. return \false;
  74656. }
  74657. private function runClean(array $sections, bool $collectCoverage): void
  74658. {
  74659. $this->phpUtil->setStdin('');
  74660. $this->phpUtil->setArgs('');
  74661. if (isset($sections['CLEAN'])) {
  74662. $cleanCode = $this->render($sections['CLEAN']);
  74663. $this->phpUtil->runJob($cleanCode, $this->settings($collectCoverage));
  74664. }
  74665. }
  74666. /**
  74667. * @throws Exception
  74668. */
  74669. private function parse(): array
  74670. {
  74671. $sections = [];
  74672. $section = '';
  74673. $unsupportedSections = ['CGI', 'COOKIE', 'DEFLATE_POST', 'EXPECTHEADERS', 'EXTENSIONS', 'GET', 'GZIP_POST', 'HEADERS', 'PHPDBG', 'POST', 'POST_RAW', 'PUT', 'REDIRECTTEST', 'REQUEST'];
  74674. $lineNr = 0;
  74675. foreach (file($this->filename) as $line) {
  74676. $lineNr++;
  74677. if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
  74678. $section = $result[1];
  74679. $sections[$section] = '';
  74680. $sections[$section . '_offset'] = $lineNr;
  74681. continue;
  74682. }
  74683. if (empty($section)) {
  74684. throw new \PHPUnit\Runner\InvalidPhptFileException();
  74685. }
  74686. $sections[$section] .= $line;
  74687. }
  74688. if (isset($sections['FILEEOF'])) {
  74689. $sections['FILE'] = rtrim($sections['FILEEOF'], "\r\n");
  74690. unset($sections['FILEEOF']);
  74691. }
  74692. $this->parseExternal($sections);
  74693. if (!$this->validate($sections)) {
  74694. throw new \PHPUnit\Runner\InvalidPhptFileException();
  74695. }
  74696. foreach ($unsupportedSections as $section) {
  74697. if (isset($sections[$section])) {
  74698. throw new \PHPUnit\Runner\UnsupportedPhptSectionException($section);
  74699. }
  74700. }
  74701. return $sections;
  74702. }
  74703. /**
  74704. * @throws Exception
  74705. */
  74706. private function parseExternal(array &$sections): void
  74707. {
  74708. $allowSections = ['FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX'];
  74709. $testDirectory = dirname($this->filename) . DIRECTORY_SEPARATOR;
  74710. foreach ($allowSections as $section) {
  74711. if (isset($sections[$section . '_EXTERNAL'])) {
  74712. $externalFilename = trim($sections[$section . '_EXTERNAL']);
  74713. if (!is_file($testDirectory . $externalFilename) || !is_readable($testDirectory . $externalFilename)) {
  74714. throw new \PHPUnit\Runner\PhptExternalFileCannotBeLoadedException($section, $testDirectory . $externalFilename);
  74715. }
  74716. $sections[$section] = file_get_contents($testDirectory . $externalFilename);
  74717. }
  74718. }
  74719. }
  74720. private function validate(array $sections): bool
  74721. {
  74722. $requiredSections = ['FILE', ['EXPECT', 'EXPECTF', 'EXPECTREGEX']];
  74723. foreach ($requiredSections as $section) {
  74724. if (is_array($section)) {
  74725. $foundSection = \false;
  74726. foreach ($section as $anySection) {
  74727. if (isset($sections[$anySection])) {
  74728. $foundSection = \true;
  74729. break;
  74730. }
  74731. }
  74732. if (!$foundSection) {
  74733. return \false;
  74734. }
  74735. continue;
  74736. }
  74737. if (!isset($sections[$section])) {
  74738. return \false;
  74739. }
  74740. }
  74741. return \true;
  74742. }
  74743. private function render(string $code): string
  74744. {
  74745. return str_replace(['__DIR__', '__FILE__'], ["'" . dirname($this->filename) . "'", "'" . $this->filename . "'"], $code);
  74746. }
  74747. private function getCoverageFiles(): array
  74748. {
  74749. $baseDir = dirname(realpath($this->filename)) . DIRECTORY_SEPARATOR;
  74750. $basename = basename($this->filename, 'phpt');
  74751. return ['coverage' => $baseDir . $basename . 'coverage', 'job' => $baseDir . $basename . 'php'];
  74752. }
  74753. /**
  74754. * @throws \SebastianBergmann\Template\InvalidArgumentException
  74755. */
  74756. private function renderForCoverage(string &$job, bool $pathCoverage, ?string $codeCoverageCacheDirectory): void
  74757. {
  74758. $files = $this->getCoverageFiles();
  74759. $template = new Template(__DIR__ . '/../Util/PHP/Template/PhptTestCase.tpl');
  74760. $composerAutoload = '\'\'';
  74761. if (defined('PHPUNIT_COMPOSER_INSTALL')) {
  74762. $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, \true);
  74763. }
  74764. $phar = '\'\'';
  74765. if (defined('__PHPUNIT_PHAR__')) {
  74766. $phar = var_export(__PHPUNIT_PHAR__, \true);
  74767. }
  74768. if ($codeCoverageCacheDirectory === null) {
  74769. $codeCoverageCacheDirectory = 'null';
  74770. } else {
  74771. $codeCoverageCacheDirectory = "'" . $codeCoverageCacheDirectory . "'";
  74772. }
  74773. $bootstrap = '';
  74774. if (ConfigurationRegistry::get()->hasBootstrap()) {
  74775. $bootstrap = ConfigurationRegistry::get()->bootstrap();
  74776. }
  74777. $template->setVar(['bootstrap' => $bootstrap, 'composerAutoload' => $composerAutoload, 'phar' => $phar, 'job' => $files['job'], 'coverageFile' => $files['coverage'], 'driverMethod' => $pathCoverage ? 'forLineAndPathCoverage' : 'forLineCoverage', 'codeCoverageCacheDirectory' => $codeCoverageCacheDirectory]);
  74778. file_put_contents($files['job'], $job);
  74779. $job = $template->render();
  74780. }
  74781. private function cleanupForCoverage(): RawCodeCoverageData
  74782. {
  74783. $coverage = RawCodeCoverageData::fromXdebugWithoutPathCoverage([]);
  74784. $files = $this->getCoverageFiles();
  74785. $buffer = \false;
  74786. if (is_file($files['coverage'])) {
  74787. $buffer = @file_get_contents($files['coverage']);
  74788. }
  74789. if ($buffer !== \false) {
  74790. $coverage = @unserialize($buffer);
  74791. if ($coverage === \false) {
  74792. $coverage = RawCodeCoverageData::fromXdebugWithoutPathCoverage([]);
  74793. }
  74794. }
  74795. foreach ($files as $file) {
  74796. @unlink($file);
  74797. }
  74798. return $coverage;
  74799. }
  74800. private function stringifyIni(array $ini): array
  74801. {
  74802. $settings = [];
  74803. foreach ($ini as $key => $value) {
  74804. if (is_array($value)) {
  74805. foreach ($value as $val) {
  74806. $settings[] = $key . '=' . $val;
  74807. }
  74808. continue;
  74809. }
  74810. $settings[] = $key . '=' . $value;
  74811. }
  74812. return $settings;
  74813. }
  74814. private function getLocationHintFromDiff(string $message, array $sections): array
  74815. {
  74816. $needle = '';
  74817. $previousLine = '';
  74818. $block = 'message';
  74819. foreach (preg_split('/\r\n|\r|\n/', $message) as $line) {
  74820. $line = trim($line);
  74821. if ($block === 'message' && $line === '--- Expected') {
  74822. $block = 'expected';
  74823. }
  74824. if ($block === 'expected' && $line === '@@ @@') {
  74825. $block = 'diff';
  74826. }
  74827. if ($block === 'diff') {
  74828. if (str_starts_with($line, '+')) {
  74829. $needle = $this->getCleanDiffLine($previousLine);
  74830. break;
  74831. }
  74832. if (str_starts_with($line, '-')) {
  74833. $needle = $this->getCleanDiffLine($line);
  74834. break;
  74835. }
  74836. }
  74837. if (!empty($line)) {
  74838. $previousLine = $line;
  74839. }
  74840. }
  74841. return $this->getLocationHint($needle, $sections);
  74842. }
  74843. private function getCleanDiffLine(string $line): string
  74844. {
  74845. if (preg_match('/^[\-+]([\'\"]?)(.*)\1$/', $line, $matches)) {
  74846. $line = $matches[2];
  74847. }
  74848. return $line;
  74849. }
  74850. private function getLocationHint(string $needle, array $sections): array
  74851. {
  74852. $needle = trim($needle);
  74853. if (empty($needle)) {
  74854. return [['file' => realpath($this->filename), 'line' => 1]];
  74855. }
  74856. $search = [
  74857. // 'FILE',
  74858. 'EXPECT',
  74859. 'EXPECTF',
  74860. 'EXPECTREGEX',
  74861. ];
  74862. foreach ($search as $section) {
  74863. if (!isset($sections[$section])) {
  74864. continue;
  74865. }
  74866. if (isset($sections[$section . '_EXTERNAL'])) {
  74867. $externalFile = trim($sections[$section . '_EXTERNAL']);
  74868. return [['file' => realpath(dirname($this->filename) . DIRECTORY_SEPARATOR . $externalFile), 'line' => 1], ['file' => realpath($this->filename), 'line' => ($sections[$section . '_EXTERNAL_offset'] ?? 0) + 1]];
  74869. }
  74870. $sectionOffset = $sections[$section . '_offset'] ?? 0;
  74871. $offset = $sectionOffset + 1;
  74872. foreach (preg_split('/\r\n|\r|\n/', $sections[$section]) as $line) {
  74873. if (str_contains($line, $needle)) {
  74874. return [['file' => realpath($this->filename), 'line' => $offset]];
  74875. }
  74876. $offset++;
  74877. }
  74878. }
  74879. return [['file' => realpath($this->filename), 'line' => 1]];
  74880. }
  74881. /**
  74882. * @psalm-return list<string>
  74883. */
  74884. private function settings(bool $collectCoverage): array
  74885. {
  74886. $settings = ['allow_url_fopen=1', 'auto_append_file=', 'auto_prepend_file=', 'disable_functions=', 'display_errors=1', 'docref_ext=.html', 'docref_root=', 'error_append_string=', 'error_prepend_string=', 'error_reporting=-1', 'html_errors=0', 'log_errors=0', 'open_basedir=', 'output_buffering=Off', 'output_handler=', 'report_memleaks=0', 'report_zend_debug=0'];
  74887. if (extension_loaded('pcov')) {
  74888. if ($collectCoverage) {
  74889. $settings[] = 'pcov.enabled=1';
  74890. } else {
  74891. $settings[] = 'pcov.enabled=0';
  74892. }
  74893. }
  74894. if (extension_loaded('xdebug')) {
  74895. if ($collectCoverage) {
  74896. $settings[] = 'xdebug.mode=coverage';
  74897. } else {
  74898. $settings[] = 'xdebug.mode=off';
  74899. }
  74900. }
  74901. return $settings;
  74902. }
  74903. }
  74904. <?php
  74905. declare (strict_types=1);
  74906. /*
  74907. * This file is part of PHPUnit.
  74908. *
  74909. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  74910. *
  74911. * For the full copyright and license information, please view the LICENSE
  74912. * file that was distributed with this source code.
  74913. */
  74914. namespace PHPUnit\Runner\ResultCache;
  74915. use const DIRECTORY_SEPARATOR;
  74916. use const LOCK_EX;
  74917. use function array_keys;
  74918. use function assert;
  74919. use function dirname;
  74920. use function file_get_contents;
  74921. use function file_put_contents;
  74922. use function is_array;
  74923. use function is_dir;
  74924. use function is_file;
  74925. use function json_decode;
  74926. use function json_encode;
  74927. use PHPUnit\Framework\TestStatus\TestStatus;
  74928. use PHPUnit\Runner\DirectoryDoesNotExistException;
  74929. use PHPUnit\Runner\Exception;
  74930. use PHPUnit\Util\Filesystem;
  74931. /**
  74932. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  74933. *
  74934. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  74935. */
  74936. final class DefaultResultCache implements \PHPUnit\Runner\ResultCache\ResultCache
  74937. {
  74938. /**
  74939. * @var int
  74940. */
  74941. private const VERSION = 1;
  74942. /**
  74943. * @var string
  74944. */
  74945. private const DEFAULT_RESULT_CACHE_FILENAME = '.phpunit.result.cache';
  74946. private readonly string $cacheFilename;
  74947. /**
  74948. * @psalm-var array<string, TestStatus>
  74949. */
  74950. private array $defects = [];
  74951. /**
  74952. * @psalm-var array<string, float>
  74953. */
  74954. private array $times = [];
  74955. public function __construct(?string $filepath = null)
  74956. {
  74957. if ($filepath !== null && is_dir($filepath)) {
  74958. $filepath .= DIRECTORY_SEPARATOR . self::DEFAULT_RESULT_CACHE_FILENAME;
  74959. }
  74960. $this->cacheFilename = $filepath ?? $_ENV['PHPUNIT_RESULT_CACHE'] ?? self::DEFAULT_RESULT_CACHE_FILENAME;
  74961. }
  74962. public function setStatus(string $id, TestStatus $status): void
  74963. {
  74964. if ($status->isSuccess()) {
  74965. return;
  74966. }
  74967. $this->defects[$id] = $status;
  74968. }
  74969. public function status(string $id): TestStatus
  74970. {
  74971. return $this->defects[$id] ?? TestStatus::unknown();
  74972. }
  74973. public function setTime(string $id, float $time): void
  74974. {
  74975. $this->times[$id] = $time;
  74976. }
  74977. public function time(string $id): float
  74978. {
  74979. return $this->times[$id] ?? 0.0;
  74980. }
  74981. public function mergeWith(self $other): void
  74982. {
  74983. foreach ($other->defects as $id => $defect) {
  74984. $this->defects[$id] = $defect;
  74985. }
  74986. foreach ($other->times as $id => $time) {
  74987. $this->times[$id] = $time;
  74988. }
  74989. }
  74990. public function load(): void
  74991. {
  74992. if (!is_file($this->cacheFilename)) {
  74993. return;
  74994. }
  74995. $contents = file_get_contents($this->cacheFilename);
  74996. if ($contents === \false) {
  74997. return;
  74998. }
  74999. $data = json_decode($contents, \true);
  75000. if ($data === null) {
  75001. return;
  75002. }
  75003. if (!isset($data['version'])) {
  75004. return;
  75005. }
  75006. if ($data['version'] !== self::VERSION) {
  75007. return;
  75008. }
  75009. assert(isset($data['defects']) && is_array($data['defects']));
  75010. assert(isset($data['times']) && is_array($data['times']));
  75011. foreach (array_keys($data['defects']) as $test) {
  75012. $data['defects'][$test] = TestStatus::from($data['defects'][$test]);
  75013. }
  75014. $this->defects = $data['defects'];
  75015. $this->times = $data['times'];
  75016. }
  75017. /**
  75018. * @throws Exception
  75019. */
  75020. public function persist(): void
  75021. {
  75022. if (!Filesystem::createDirectory(dirname($this->cacheFilename))) {
  75023. throw new DirectoryDoesNotExistException(dirname($this->cacheFilename));
  75024. }
  75025. $data = ['version' => self::VERSION, 'defects' => [], 'times' => $this->times];
  75026. foreach ($this->defects as $test => $status) {
  75027. $data['defects'][$test] = $status->asInt();
  75028. }
  75029. file_put_contents($this->cacheFilename, json_encode($data), LOCK_EX);
  75030. }
  75031. }
  75032. <?php
  75033. declare (strict_types=1);
  75034. /*
  75035. * This file is part of PHPUnit.
  75036. *
  75037. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75038. *
  75039. * For the full copyright and license information, please view the LICENSE
  75040. * file that was distributed with this source code.
  75041. */
  75042. namespace PHPUnit\Runner\ResultCache;
  75043. use PHPUnit\Framework\TestStatus\TestStatus;
  75044. /**
  75045. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75046. *
  75047. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75048. */
  75049. final class NullResultCache implements \PHPUnit\Runner\ResultCache\ResultCache
  75050. {
  75051. public function setStatus(string $id, TestStatus $status): void
  75052. {
  75053. }
  75054. public function status(string $id): TestStatus
  75055. {
  75056. return TestStatus::unknown();
  75057. }
  75058. public function setTime(string $id, float $time): void
  75059. {
  75060. }
  75061. public function time(string $id): float
  75062. {
  75063. return 0;
  75064. }
  75065. public function load(): void
  75066. {
  75067. }
  75068. public function persist(): void
  75069. {
  75070. }
  75071. }
  75072. <?php
  75073. declare (strict_types=1);
  75074. /*
  75075. * This file is part of PHPUnit.
  75076. *
  75077. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75078. *
  75079. * For the full copyright and license information, please view the LICENSE
  75080. * file that was distributed with this source code.
  75081. */
  75082. namespace PHPUnit\Runner\ResultCache;
  75083. use PHPUnit\Framework\TestStatus\TestStatus;
  75084. /**
  75085. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75086. *
  75087. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75088. */
  75089. interface ResultCache
  75090. {
  75091. public function setStatus(string $id, TestStatus $status): void;
  75092. public function status(string $id): TestStatus;
  75093. public function setTime(string $id, float $time): void;
  75094. public function time(string $id): float;
  75095. public function load(): void;
  75096. public function persist(): void;
  75097. }
  75098. <?php
  75099. declare (strict_types=1);
  75100. /*
  75101. * This file is part of PHPUnit.
  75102. *
  75103. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75104. *
  75105. * For the full copyright and license information, please view the LICENSE
  75106. * file that was distributed with this source code.
  75107. */
  75108. namespace PHPUnit\Runner\ResultCache;
  75109. use function round;
  75110. use PHPUnit\Event\Event;
  75111. use PHPUnit\Event\EventFacadeIsSealedException;
  75112. use PHPUnit\Event\Facade;
  75113. use PHPUnit\Event\Telemetry\HRTime;
  75114. use PHPUnit\Event\Test\ConsideredRisky;
  75115. use PHPUnit\Event\Test\Errored;
  75116. use PHPUnit\Event\Test\Failed;
  75117. use PHPUnit\Event\Test\Finished;
  75118. use PHPUnit\Event\Test\MarkedIncomplete;
  75119. use PHPUnit\Event\Test\Prepared;
  75120. use PHPUnit\Event\Test\Skipped;
  75121. use PHPUnit\Event\UnknownSubscriberTypeException;
  75122. use PHPUnit\Framework\InvalidArgumentException;
  75123. use PHPUnit\Framework\TestStatus\TestStatus;
  75124. /**
  75125. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75126. *
  75127. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75128. */
  75129. final class ResultCacheHandler
  75130. {
  75131. private readonly \PHPUnit\Runner\ResultCache\ResultCache $cache;
  75132. private ?HRTime $time = null;
  75133. private int $testSuite = 0;
  75134. /**
  75135. * @throws EventFacadeIsSealedException
  75136. * @throws UnknownSubscriberTypeException
  75137. */
  75138. public function __construct(\PHPUnit\Runner\ResultCache\ResultCache $cache, Facade $facade)
  75139. {
  75140. $this->cache = $cache;
  75141. $this->registerSubscribers($facade);
  75142. }
  75143. public function testSuiteStarted(): void
  75144. {
  75145. $this->testSuite++;
  75146. }
  75147. public function testSuiteFinished(): void
  75148. {
  75149. $this->testSuite--;
  75150. if ($this->testSuite === 0) {
  75151. $this->cache->persist();
  75152. }
  75153. }
  75154. public function testPrepared(Prepared $event): void
  75155. {
  75156. $this->time = $event->telemetryInfo()->time();
  75157. }
  75158. public function testMarkedIncomplete(MarkedIncomplete $event): void
  75159. {
  75160. $this->cache->setStatus($event->test()->id(), TestStatus::incomplete($event->throwable()->message()));
  75161. }
  75162. public function testConsideredRisky(ConsideredRisky $event): void
  75163. {
  75164. $this->cache->setStatus($event->test()->id(), TestStatus::risky($event->message()));
  75165. }
  75166. public function testErrored(Errored $event): void
  75167. {
  75168. $this->cache->setStatus($event->test()->id(), TestStatus::error($event->throwable()->message()));
  75169. }
  75170. public function testFailed(Failed $event): void
  75171. {
  75172. $this->cache->setStatus($event->test()->id(), TestStatus::failure($event->throwable()->message()));
  75173. }
  75174. /**
  75175. * @throws \PHPUnit\Event\InvalidArgumentException
  75176. * @throws InvalidArgumentException
  75177. */
  75178. public function testSkipped(Skipped $event): void
  75179. {
  75180. $this->cache->setStatus($event->test()->id(), TestStatus::skipped($event->message()));
  75181. $this->cache->setTime($event->test()->id(), $this->duration($event));
  75182. }
  75183. /**
  75184. * @throws \PHPUnit\Event\InvalidArgumentException
  75185. * @throws InvalidArgumentException
  75186. */
  75187. public function testFinished(Finished $event): void
  75188. {
  75189. $this->cache->setTime($event->test()->id(), $this->duration($event));
  75190. $this->time = null;
  75191. }
  75192. /**
  75193. * @throws \PHPUnit\Event\InvalidArgumentException
  75194. * @throws InvalidArgumentException
  75195. */
  75196. private function duration(Event $event): float
  75197. {
  75198. if ($this->time === null) {
  75199. return 0.0;
  75200. }
  75201. return round($event->telemetryInfo()->time()->duration($this->time)->asFloat(), 3);
  75202. }
  75203. /**
  75204. * @throws EventFacadeIsSealedException
  75205. * @throws UnknownSubscriberTypeException
  75206. */
  75207. private function registerSubscribers(Facade $facade): void
  75208. {
  75209. $facade->registerSubscribers(new \PHPUnit\Runner\ResultCache\TestSuiteStartedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSuiteFinishedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestPreparedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Runner\ResultCache\TestConsideredRiskySubscriber($this), new \PHPUnit\Runner\ResultCache\TestErroredSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFailedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSkippedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFinishedSubscriber($this));
  75210. }
  75211. }
  75212. <?php
  75213. declare (strict_types=1);
  75214. /*
  75215. * This file is part of PHPUnit.
  75216. *
  75217. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75218. *
  75219. * For the full copyright and license information, please view the LICENSE
  75220. * file that was distributed with this source code.
  75221. */
  75222. namespace PHPUnit\Runner\ResultCache;
  75223. /**
  75224. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75225. *
  75226. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75227. */
  75228. abstract class Subscriber
  75229. {
  75230. private readonly \PHPUnit\Runner\ResultCache\ResultCacheHandler $handler;
  75231. public function __construct(\PHPUnit\Runner\ResultCache\ResultCacheHandler $handler)
  75232. {
  75233. $this->handler = $handler;
  75234. }
  75235. protected function handler(): \PHPUnit\Runner\ResultCache\ResultCacheHandler
  75236. {
  75237. return $this->handler;
  75238. }
  75239. }
  75240. <?php
  75241. declare (strict_types=1);
  75242. /*
  75243. * This file is part of PHPUnit.
  75244. *
  75245. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75246. *
  75247. * For the full copyright and license information, please view the LICENSE
  75248. * file that was distributed with this source code.
  75249. */
  75250. namespace PHPUnit\Runner\ResultCache;
  75251. use PHPUnit\Event\Test\ConsideredRisky;
  75252. use PHPUnit\Event\Test\ConsideredRiskySubscriber;
  75253. /**
  75254. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75255. *
  75256. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75257. */
  75258. final class TestConsideredRiskySubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements ConsideredRiskySubscriber
  75259. {
  75260. public function notify(ConsideredRisky $event): void
  75261. {
  75262. $this->handler()->testConsideredRisky($event);
  75263. }
  75264. }
  75265. <?php
  75266. declare (strict_types=1);
  75267. /*
  75268. * This file is part of PHPUnit.
  75269. *
  75270. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75271. *
  75272. * For the full copyright and license information, please view the LICENSE
  75273. * file that was distributed with this source code.
  75274. */
  75275. namespace PHPUnit\Runner\ResultCache;
  75276. use PHPUnit\Event\Test\Errored;
  75277. use PHPUnit\Event\Test\ErroredSubscriber;
  75278. /**
  75279. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75280. *
  75281. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75282. */
  75283. final class TestErroredSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements ErroredSubscriber
  75284. {
  75285. public function notify(Errored $event): void
  75286. {
  75287. $this->handler()->testErrored($event);
  75288. }
  75289. }
  75290. <?php
  75291. declare (strict_types=1);
  75292. /*
  75293. * This file is part of PHPUnit.
  75294. *
  75295. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75296. *
  75297. * For the full copyright and license information, please view the LICENSE
  75298. * file that was distributed with this source code.
  75299. */
  75300. namespace PHPUnit\Runner\ResultCache;
  75301. use PHPUnit\Event\Test\Failed;
  75302. use PHPUnit\Event\Test\FailedSubscriber;
  75303. /**
  75304. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75305. *
  75306. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75307. */
  75308. final class TestFailedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FailedSubscriber
  75309. {
  75310. public function notify(Failed $event): void
  75311. {
  75312. $this->handler()->testFailed($event);
  75313. }
  75314. }
  75315. <?php
  75316. declare (strict_types=1);
  75317. /*
  75318. * This file is part of PHPUnit.
  75319. *
  75320. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75321. *
  75322. * For the full copyright and license information, please view the LICENSE
  75323. * file that was distributed with this source code.
  75324. */
  75325. namespace PHPUnit\Runner\ResultCache;
  75326. use PHPUnit\Event\InvalidArgumentException;
  75327. use PHPUnit\Event\Test\Finished;
  75328. use PHPUnit\Event\Test\FinishedSubscriber;
  75329. /**
  75330. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75331. *
  75332. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75333. */
  75334. final class TestFinishedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FinishedSubscriber
  75335. {
  75336. /**
  75337. * @throws \PHPUnit\Framework\InvalidArgumentException
  75338. * @throws InvalidArgumentException
  75339. */
  75340. public function notify(Finished $event): void
  75341. {
  75342. $this->handler()->testFinished($event);
  75343. }
  75344. }
  75345. <?php
  75346. declare (strict_types=1);
  75347. /*
  75348. * This file is part of PHPUnit.
  75349. *
  75350. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75351. *
  75352. * For the full copyright and license information, please view the LICENSE
  75353. * file that was distributed with this source code.
  75354. */
  75355. namespace PHPUnit\Runner\ResultCache;
  75356. use PHPUnit\Event\Test\MarkedIncomplete;
  75357. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  75358. /**
  75359. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75360. *
  75361. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75362. */
  75363. final class TestMarkedIncompleteSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements MarkedIncompleteSubscriber
  75364. {
  75365. public function notify(MarkedIncomplete $event): void
  75366. {
  75367. $this->handler()->testMarkedIncomplete($event);
  75368. }
  75369. }
  75370. <?php
  75371. declare (strict_types=1);
  75372. /*
  75373. * This file is part of PHPUnit.
  75374. *
  75375. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75376. *
  75377. * For the full copyright and license information, please view the LICENSE
  75378. * file that was distributed with this source code.
  75379. */
  75380. namespace PHPUnit\Runner\ResultCache;
  75381. use PHPUnit\Event\Test\Prepared;
  75382. use PHPUnit\Event\Test\PreparedSubscriber;
  75383. /**
  75384. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75385. *
  75386. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75387. */
  75388. final class TestPreparedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements PreparedSubscriber
  75389. {
  75390. public function notify(Prepared $event): void
  75391. {
  75392. $this->handler()->testPrepared($event);
  75393. }
  75394. }
  75395. <?php
  75396. declare (strict_types=1);
  75397. /*
  75398. * This file is part of PHPUnit.
  75399. *
  75400. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75401. *
  75402. * For the full copyright and license information, please view the LICENSE
  75403. * file that was distributed with this source code.
  75404. */
  75405. namespace PHPUnit\Runner\ResultCache;
  75406. use PHPUnit\Event\InvalidArgumentException;
  75407. use PHPUnit\Event\Test\Skipped;
  75408. use PHPUnit\Event\Test\SkippedSubscriber;
  75409. /**
  75410. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75411. *
  75412. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75413. */
  75414. final class TestSkippedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements SkippedSubscriber
  75415. {
  75416. /**
  75417. * @throws \PHPUnit\Framework\InvalidArgumentException
  75418. * @throws InvalidArgumentException
  75419. */
  75420. public function notify(Skipped $event): void
  75421. {
  75422. $this->handler()->testSkipped($event);
  75423. }
  75424. }
  75425. <?php
  75426. declare (strict_types=1);
  75427. /*
  75428. * This file is part of PHPUnit.
  75429. *
  75430. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75431. *
  75432. * For the full copyright and license information, please view the LICENSE
  75433. * file that was distributed with this source code.
  75434. */
  75435. namespace PHPUnit\Runner\ResultCache;
  75436. use PHPUnit\Event\TestSuite\Finished;
  75437. use PHPUnit\Event\TestSuite\FinishedSubscriber;
  75438. /**
  75439. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75440. *
  75441. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75442. */
  75443. final class TestSuiteFinishedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FinishedSubscriber
  75444. {
  75445. public function notify(Finished $event): void
  75446. {
  75447. $this->handler()->testSuiteFinished();
  75448. }
  75449. }
  75450. <?php
  75451. declare (strict_types=1);
  75452. /*
  75453. * This file is part of PHPUnit.
  75454. *
  75455. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75456. *
  75457. * For the full copyright and license information, please view the LICENSE
  75458. * file that was distributed with this source code.
  75459. */
  75460. namespace PHPUnit\Runner\ResultCache;
  75461. use PHPUnit\Event\TestSuite\Started;
  75462. use PHPUnit\Event\TestSuite\StartedSubscriber;
  75463. /**
  75464. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75465. *
  75466. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75467. */
  75468. final class TestSuiteStartedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements StartedSubscriber
  75469. {
  75470. public function notify(Started $event): void
  75471. {
  75472. $this->handler()->testSuiteStarted();
  75473. }
  75474. }
  75475. <?php
  75476. declare (strict_types=1);
  75477. /*
  75478. * This file is part of PHPUnit.
  75479. *
  75480. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75481. *
  75482. * For the full copyright and license information, please view the LICENSE
  75483. * file that was distributed with this source code.
  75484. */
  75485. namespace PHPUnit\TestRunner\TestResult;
  75486. use function array_values;
  75487. use function assert;
  75488. use function implode;
  75489. use function str_contains;
  75490. use PHPUnit\Event\Code\TestMethod;
  75491. use PHPUnit\Event\EventFacadeIsSealedException;
  75492. use PHPUnit\Event\Facade;
  75493. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  75494. use PHPUnit\Event\Test\ConsideredRisky;
  75495. use PHPUnit\Event\Test\DeprecationTriggered;
  75496. use PHPUnit\Event\Test\Errored;
  75497. use PHPUnit\Event\Test\ErrorTriggered;
  75498. use PHPUnit\Event\Test\Failed;
  75499. use PHPUnit\Event\Test\Finished;
  75500. use PHPUnit\Event\Test\MarkedIncomplete;
  75501. use PHPUnit\Event\Test\NoticeTriggered;
  75502. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  75503. use PHPUnit\Event\Test\PhpNoticeTriggered;
  75504. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  75505. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  75506. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  75507. use PHPUnit\Event\Test\PhpWarningTriggered;
  75508. use PHPUnit\Event\Test\Skipped as TestSkipped;
  75509. use PHPUnit\Event\Test\WarningTriggered;
  75510. use PHPUnit\Event\TestRunner\DeprecationTriggered as TestRunnerDeprecationTriggered;
  75511. use PHPUnit\Event\TestRunner\ExecutionStarted;
  75512. use PHPUnit\Event\TestRunner\WarningTriggered as TestRunnerWarningTriggered;
  75513. use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
  75514. use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
  75515. use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
  75516. use PHPUnit\Event\TestSuite\TestSuiteForTestClass;
  75517. use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
  75518. use PHPUnit\Event\UnknownSubscriberTypeException;
  75519. use PHPUnit\TestRunner\TestResult\Issues\Issue;
  75520. use PHPUnit\TextUI\Configuration\Source;
  75521. use PHPUnit\TextUI\Configuration\SourceFilter;
  75522. /**
  75523. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75524. *
  75525. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75526. */
  75527. final class Collector
  75528. {
  75529. private readonly Source $source;
  75530. private int $numberOfTests = 0;
  75531. private int $numberOfTestsRun = 0;
  75532. private int $numberOfAssertions = 0;
  75533. private bool $prepared = \false;
  75534. private bool $currentTestSuiteForTestClassFailed = \false;
  75535. /**
  75536. * @psalm-var non-negative-int
  75537. */
  75538. private int $numberOfIssuesIgnoredByBaseline = 0;
  75539. /**
  75540. * @psalm-var list<BeforeFirstTestMethodErrored|Errored>
  75541. */
  75542. private array $testErroredEvents = [];
  75543. /**
  75544. * @psalm-var list<Failed>
  75545. */
  75546. private array $testFailedEvents = [];
  75547. /**
  75548. * @psalm-var list<MarkedIncomplete>
  75549. */
  75550. private array $testMarkedIncompleteEvents = [];
  75551. /**
  75552. * @psalm-var list<TestSuiteSkipped>
  75553. */
  75554. private array $testSuiteSkippedEvents = [];
  75555. /**
  75556. * @psalm-var list<TestSkipped>
  75557. */
  75558. private array $testSkippedEvents = [];
  75559. /**
  75560. * @psalm-var array<string,list<ConsideredRisky>>
  75561. */
  75562. private array $testConsideredRiskyEvents = [];
  75563. /**
  75564. * @psalm-var array<string,list<PhpunitDeprecationTriggered>>
  75565. */
  75566. private array $testTriggeredPhpunitDeprecationEvents = [];
  75567. /**
  75568. * @psalm-var array<string,list<PhpunitErrorTriggered>>
  75569. */
  75570. private array $testTriggeredPhpunitErrorEvents = [];
  75571. /**
  75572. * @psalm-var array<string,list<PhpunitWarningTriggered>>
  75573. */
  75574. private array $testTriggeredPhpunitWarningEvents = [];
  75575. /**
  75576. * @psalm-var list<TestRunnerWarningTriggered>
  75577. */
  75578. private array $testRunnerTriggeredWarningEvents = [];
  75579. /**
  75580. * @psalm-var list<TestRunnerDeprecationTriggered>
  75581. */
  75582. private array $testRunnerTriggeredDeprecationEvents = [];
  75583. /**
  75584. * @psalm-var array<non-empty-string, Issue>
  75585. */
  75586. private array $errors = [];
  75587. /**
  75588. * @psalm-var array<non-empty-string, Issue>
  75589. */
  75590. private array $deprecations = [];
  75591. /**
  75592. * @psalm-var array<non-empty-string, Issue>
  75593. */
  75594. private array $notices = [];
  75595. /**
  75596. * @psalm-var array<non-empty-string, Issue>
  75597. */
  75598. private array $warnings = [];
  75599. /**
  75600. * @psalm-var array<non-empty-string, Issue>
  75601. */
  75602. private array $phpDeprecations = [];
  75603. /**
  75604. * @psalm-var array<non-empty-string, Issue>
  75605. */
  75606. private array $phpNotices = [];
  75607. /**
  75608. * @psalm-var array<non-empty-string, Issue>
  75609. */
  75610. private array $phpWarnings = [];
  75611. /**
  75612. * @throws EventFacadeIsSealedException
  75613. * @throws UnknownSubscriberTypeException
  75614. */
  75615. public function __construct(Facade $facade, Source $source)
  75616. {
  75617. $facade->registerSubscribers(new \PHPUnit\TestRunner\TestResult\ExecutionStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestPreparedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFailedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestConsideredRiskySubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredWarningSubscriber($this));
  75618. $this->source = $source;
  75619. }
  75620. public function result(): \PHPUnit\TestRunner\TestResult\TestResult
  75621. {
  75622. return new \PHPUnit\TestRunner\TestResult\TestResult($this->numberOfTests, $this->numberOfTestsRun, $this->numberOfAssertions, $this->testErroredEvents, $this->testFailedEvents, $this->testConsideredRiskyEvents, $this->testSuiteSkippedEvents, $this->testSkippedEvents, $this->testMarkedIncompleteEvents, $this->testTriggeredPhpunitDeprecationEvents, $this->testTriggeredPhpunitErrorEvents, $this->testTriggeredPhpunitWarningEvents, $this->testRunnerTriggeredDeprecationEvents, $this->testRunnerTriggeredWarningEvents, array_values($this->errors), array_values($this->deprecations), array_values($this->notices), array_values($this->warnings), array_values($this->phpDeprecations), array_values($this->phpNotices), array_values($this->phpWarnings), $this->numberOfIssuesIgnoredByBaseline);
  75623. }
  75624. public function executionStarted(ExecutionStarted $event): void
  75625. {
  75626. $this->numberOfTests = $event->testSuite()->count();
  75627. }
  75628. public function testSuiteSkipped(TestSuiteSkipped $event): void
  75629. {
  75630. $testSuite = $event->testSuite();
  75631. if (!$testSuite->isForTestClass()) {
  75632. return;
  75633. }
  75634. $this->testSuiteSkippedEvents[] = $event;
  75635. }
  75636. public function testSuiteStarted(TestSuiteStarted $event): void
  75637. {
  75638. $testSuite = $event->testSuite();
  75639. if (!$testSuite->isForTestClass()) {
  75640. return;
  75641. }
  75642. $this->currentTestSuiteForTestClassFailed = \false;
  75643. }
  75644. public function testSuiteFinished(TestSuiteFinished $event): void
  75645. {
  75646. if ($this->currentTestSuiteForTestClassFailed) {
  75647. return;
  75648. }
  75649. $testSuite = $event->testSuite();
  75650. if ($testSuite->isWithName()) {
  75651. return;
  75652. }
  75653. if ($testSuite->isForTestMethodWithDataProvider()) {
  75654. assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
  75655. $test = $testSuite->tests()->asArray()[0];
  75656. assert($test instanceof TestMethod);
  75657. \PHPUnit\TestRunner\TestResult\PassedTests::instance()->testMethodPassed($test, null);
  75658. return;
  75659. }
  75660. assert($testSuite instanceof TestSuiteForTestClass);
  75661. \PHPUnit\TestRunner\TestResult\PassedTests::instance()->testClassPassed($testSuite->className());
  75662. }
  75663. public function testPrepared(): void
  75664. {
  75665. $this->prepared = \true;
  75666. }
  75667. public function testFinished(Finished $event): void
  75668. {
  75669. $this->numberOfAssertions += $event->numberOfAssertionsPerformed();
  75670. $this->numberOfTestsRun++;
  75671. $this->prepared = \false;
  75672. }
  75673. public function beforeTestClassMethodErrored(BeforeFirstTestMethodErrored $event): void
  75674. {
  75675. $this->testErroredEvents[] = $event;
  75676. $this->numberOfTestsRun++;
  75677. }
  75678. public function testErrored(Errored $event): void
  75679. {
  75680. $this->testErroredEvents[] = $event;
  75681. $this->currentTestSuiteForTestClassFailed = \true;
  75682. /*
  75683. * @todo Eliminate this special case
  75684. */
  75685. if (str_contains($event->asString(), 'Test was run in child process and ended unexpectedly')) {
  75686. return;
  75687. }
  75688. if (!$this->prepared) {
  75689. $this->numberOfTestsRun++;
  75690. }
  75691. }
  75692. public function testFailed(Failed $event): void
  75693. {
  75694. $this->testFailedEvents[] = $event;
  75695. $this->currentTestSuiteForTestClassFailed = \true;
  75696. }
  75697. public function testMarkedIncomplete(MarkedIncomplete $event): void
  75698. {
  75699. $this->testMarkedIncompleteEvents[] = $event;
  75700. }
  75701. public function testSkipped(TestSkipped $event): void
  75702. {
  75703. $this->testSkippedEvents[] = $event;
  75704. if (!$this->prepared) {
  75705. $this->numberOfTestsRun++;
  75706. }
  75707. }
  75708. public function testConsideredRisky(ConsideredRisky $event): void
  75709. {
  75710. if (!isset($this->testConsideredRiskyEvents[$event->test()->id()])) {
  75711. $this->testConsideredRiskyEvents[$event->test()->id()] = [];
  75712. }
  75713. $this->testConsideredRiskyEvents[$event->test()->id()][] = $event;
  75714. }
  75715. public function testTriggeredDeprecation(DeprecationTriggered $event): void
  75716. {
  75717. if ($event->ignoredByTest()) {
  75718. return;
  75719. }
  75720. if ($event->ignoredByBaseline()) {
  75721. $this->numberOfIssuesIgnoredByBaseline++;
  75722. return;
  75723. }
  75724. if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
  75725. return;
  75726. }
  75727. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75728. return;
  75729. }
  75730. $id = $this->issueId($event);
  75731. if (!isset($this->deprecations[$id])) {
  75732. $this->deprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75733. return;
  75734. }
  75735. $this->deprecations[$id]->triggeredBy($event->test());
  75736. }
  75737. public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
  75738. {
  75739. if ($event->ignoredByTest()) {
  75740. return;
  75741. }
  75742. if ($event->ignoredByBaseline()) {
  75743. $this->numberOfIssuesIgnoredByBaseline++;
  75744. return;
  75745. }
  75746. if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
  75747. return;
  75748. }
  75749. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75750. return;
  75751. }
  75752. $id = $this->issueId($event);
  75753. if (!isset($this->phpDeprecations[$id])) {
  75754. $this->phpDeprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75755. return;
  75756. }
  75757. $this->phpDeprecations[$id]->triggeredBy($event->test());
  75758. }
  75759. public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event): void
  75760. {
  75761. if (!isset($this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()])) {
  75762. $this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()] = [];
  75763. }
  75764. $this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()][] = $event;
  75765. }
  75766. public function testTriggeredError(ErrorTriggered $event): void
  75767. {
  75768. if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) {
  75769. return;
  75770. }
  75771. $id = $this->issueId($event);
  75772. if (!isset($this->errors[$id])) {
  75773. $this->errors[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75774. return;
  75775. }
  75776. $this->errors[$id]->triggeredBy($event->test());
  75777. }
  75778. public function testTriggeredNotice(NoticeTriggered $event): void
  75779. {
  75780. if ($event->ignoredByBaseline()) {
  75781. $this->numberOfIssuesIgnoredByBaseline++;
  75782. return;
  75783. }
  75784. if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
  75785. return;
  75786. }
  75787. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75788. return;
  75789. }
  75790. $id = $this->issueId($event);
  75791. if (!isset($this->notices[$id])) {
  75792. $this->notices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75793. return;
  75794. }
  75795. $this->notices[$id]->triggeredBy($event->test());
  75796. }
  75797. public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
  75798. {
  75799. if ($event->ignoredByBaseline()) {
  75800. $this->numberOfIssuesIgnoredByBaseline++;
  75801. return;
  75802. }
  75803. if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
  75804. return;
  75805. }
  75806. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75807. return;
  75808. }
  75809. $id = $this->issueId($event);
  75810. if (!isset($this->phpNotices[$id])) {
  75811. $this->phpNotices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75812. return;
  75813. }
  75814. $this->phpNotices[$id]->triggeredBy($event->test());
  75815. }
  75816. public function testTriggeredWarning(WarningTriggered $event): void
  75817. {
  75818. if ($event->ignoredByBaseline()) {
  75819. $this->numberOfIssuesIgnoredByBaseline++;
  75820. return;
  75821. }
  75822. if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
  75823. return;
  75824. }
  75825. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75826. return;
  75827. }
  75828. $id = $this->issueId($event);
  75829. if (!isset($this->warnings[$id])) {
  75830. $this->warnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75831. return;
  75832. }
  75833. $this->warnings[$id]->triggeredBy($event->test());
  75834. }
  75835. public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
  75836. {
  75837. if ($event->ignoredByBaseline()) {
  75838. $this->numberOfIssuesIgnoredByBaseline++;
  75839. return;
  75840. }
  75841. if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
  75842. return;
  75843. }
  75844. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  75845. return;
  75846. }
  75847. $id = $this->issueId($event);
  75848. if (!isset($this->phpWarnings[$id])) {
  75849. $this->phpWarnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
  75850. return;
  75851. }
  75852. $this->phpWarnings[$id]->triggeredBy($event->test());
  75853. }
  75854. public function testTriggeredPhpunitError(PhpunitErrorTriggered $event): void
  75855. {
  75856. if (!isset($this->testTriggeredPhpunitErrorEvents[$event->test()->id()])) {
  75857. $this->testTriggeredPhpunitErrorEvents[$event->test()->id()] = [];
  75858. }
  75859. $this->testTriggeredPhpunitErrorEvents[$event->test()->id()][] = $event;
  75860. }
  75861. public function testTriggeredPhpunitWarning(PhpunitWarningTriggered $event): void
  75862. {
  75863. if (!isset($this->testTriggeredPhpunitWarningEvents[$event->test()->id()])) {
  75864. $this->testTriggeredPhpunitWarningEvents[$event->test()->id()] = [];
  75865. }
  75866. $this->testTriggeredPhpunitWarningEvents[$event->test()->id()][] = $event;
  75867. }
  75868. public function testRunnerTriggeredDeprecation(TestRunnerDeprecationTriggered $event): void
  75869. {
  75870. $this->testRunnerTriggeredDeprecationEvents[] = $event;
  75871. }
  75872. public function testRunnerTriggeredWarning(TestRunnerWarningTriggered $event): void
  75873. {
  75874. $this->testRunnerTriggeredWarningEvents[] = $event;
  75875. }
  75876. public function hasErroredTests(): bool
  75877. {
  75878. return !empty($this->testErroredEvents);
  75879. }
  75880. public function hasFailedTests(): bool
  75881. {
  75882. return !empty($this->testFailedEvents);
  75883. }
  75884. public function hasRiskyTests(): bool
  75885. {
  75886. return !empty($this->testConsideredRiskyEvents);
  75887. }
  75888. public function hasSkippedTests(): bool
  75889. {
  75890. return !empty($this->testSkippedEvents);
  75891. }
  75892. public function hasIncompleteTests(): bool
  75893. {
  75894. return !empty($this->testMarkedIncompleteEvents);
  75895. }
  75896. public function hasDeprecations(): bool
  75897. {
  75898. return !empty($this->deprecations) || !empty($this->phpDeprecations) || !empty($this->testTriggeredPhpunitDeprecationEvents) || !empty($this->testRunnerTriggeredDeprecationEvents);
  75899. }
  75900. public function hasNotices(): bool
  75901. {
  75902. return !empty($this->notices) || !empty($this->phpNotices);
  75903. }
  75904. public function hasWarnings(): bool
  75905. {
  75906. return !empty($this->warnings) || !empty($this->phpWarnings) || !empty($this->testTriggeredPhpunitWarningEvents) || !empty($this->testRunnerTriggeredWarningEvents);
  75907. }
  75908. /**
  75909. * @psalm-return non-empty-string
  75910. */
  75911. private function issueId(DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): string
  75912. {
  75913. return implode(':', [$event->file(), $event->line(), $event->message()]);
  75914. }
  75915. }
  75916. <?php
  75917. declare (strict_types=1);
  75918. /*
  75919. * This file is part of PHPUnit.
  75920. *
  75921. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  75922. *
  75923. * For the full copyright and license information, please view the LICENSE
  75924. * file that was distributed with this source code.
  75925. */
  75926. namespace PHPUnit\TestRunner\TestResult;
  75927. use PHPUnit\Event\EventFacadeIsSealedException;
  75928. use PHPUnit\Event\Facade as EventFacade;
  75929. use PHPUnit\Event\UnknownSubscriberTypeException;
  75930. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  75931. /**
  75932. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  75933. *
  75934. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  75935. */
  75936. final class Facade
  75937. {
  75938. private static ?\PHPUnit\TestRunner\TestResult\Collector $collector = null;
  75939. /**
  75940. * @throws EventFacadeIsSealedException
  75941. * @throws UnknownSubscriberTypeException
  75942. */
  75943. public static function init(): void
  75944. {
  75945. self::collector();
  75946. }
  75947. /**
  75948. * @throws EventFacadeIsSealedException
  75949. * @throws UnknownSubscriberTypeException
  75950. */
  75951. public static function result(): \PHPUnit\TestRunner\TestResult\TestResult
  75952. {
  75953. return self::collector()->result();
  75954. }
  75955. /**
  75956. * @throws EventFacadeIsSealedException
  75957. * @throws UnknownSubscriberTypeException
  75958. */
  75959. public static function shouldStop(): bool
  75960. {
  75961. $configuration = ConfigurationRegistry::get();
  75962. $collector = self::collector();
  75963. if (($configuration->stopOnDefect() || $configuration->stopOnError()) && $collector->hasErroredTests()) {
  75964. return \true;
  75965. }
  75966. if (($configuration->stopOnDefect() || $configuration->stopOnFailure()) && $collector->hasFailedTests()) {
  75967. return \true;
  75968. }
  75969. if (($configuration->stopOnDefect() || $configuration->stopOnWarning()) && $collector->hasWarnings()) {
  75970. return \true;
  75971. }
  75972. if (($configuration->stopOnDefect() || $configuration->stopOnRisky()) && $collector->hasRiskyTests()) {
  75973. return \true;
  75974. }
  75975. if ($configuration->stopOnDeprecation() && $collector->hasDeprecations()) {
  75976. return \true;
  75977. }
  75978. if ($configuration->stopOnNotice() && $collector->hasNotices()) {
  75979. return \true;
  75980. }
  75981. if ($configuration->stopOnIncomplete() && $collector->hasIncompleteTests()) {
  75982. return \true;
  75983. }
  75984. if ($configuration->stopOnSkipped() && $collector->hasSkippedTests()) {
  75985. return \true;
  75986. }
  75987. return \false;
  75988. }
  75989. /**
  75990. * @throws EventFacadeIsSealedException
  75991. * @throws UnknownSubscriberTypeException
  75992. */
  75993. private static function collector(): \PHPUnit\TestRunner\TestResult\Collector
  75994. {
  75995. if (self::$collector === null) {
  75996. $configuration = ConfigurationRegistry::get();
  75997. self::$collector = new \PHPUnit\TestRunner\TestResult\Collector(EventFacade::instance(), $configuration->source());
  75998. }
  75999. return self::$collector;
  76000. }
  76001. }
  76002. <?php
  76003. declare (strict_types=1);
  76004. /*
  76005. * This file is part of PHPUnit.
  76006. *
  76007. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76008. *
  76009. * For the full copyright and license information, please view the LICENSE
  76010. * file that was distributed with this source code.
  76011. */
  76012. namespace PHPUnit\TestRunner\TestResult\Issues;
  76013. use PHPUnit\Event\Code\Test;
  76014. /**
  76015. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76016. *
  76017. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76018. */
  76019. final class Issue
  76020. {
  76021. /**
  76022. * @psalm-var non-empty-string
  76023. */
  76024. private readonly string $file;
  76025. /**
  76026. * @psalm-var positive-int
  76027. */
  76028. private readonly int $line;
  76029. /**
  76030. * @psalm-var non-empty-string
  76031. */
  76032. private readonly string $description;
  76033. /**
  76034. * @psalm-var non-empty-array<non-empty-string, array{test: Test, count: int}>
  76035. */
  76036. private array $triggeringTests;
  76037. /**
  76038. * @psalm-param non-empty-string $file
  76039. * @psalm-param positive-int $line
  76040. * @psalm-param non-empty-string $description
  76041. */
  76042. public static function from(string $file, int $line, string $description, Test $triggeringTest): self
  76043. {
  76044. return new self($file, $line, $description, $triggeringTest);
  76045. }
  76046. /**
  76047. * @psalm-param non-empty-string $file
  76048. * @psalm-param positive-int $line
  76049. * @psalm-param non-empty-string $description
  76050. */
  76051. private function __construct(string $file, int $line, string $description, Test $triggeringTest)
  76052. {
  76053. $this->file = $file;
  76054. $this->line = $line;
  76055. $this->description = $description;
  76056. $this->triggeringTests = [$triggeringTest->id() => ['test' => $triggeringTest, 'count' => 1]];
  76057. }
  76058. public function triggeredBy(Test $test): void
  76059. {
  76060. if (isset($this->triggeringTests[$test->id()])) {
  76061. $this->triggeringTests[$test->id()]['count']++;
  76062. return;
  76063. }
  76064. $this->triggeringTests[$test->id()] = ['test' => $test, 'count' => 1];
  76065. }
  76066. /**
  76067. * @psalm-return non-empty-string
  76068. */
  76069. public function file(): string
  76070. {
  76071. return $this->file;
  76072. }
  76073. /**
  76074. * @psalm-return positive-int
  76075. */
  76076. public function line(): int
  76077. {
  76078. return $this->line;
  76079. }
  76080. /**
  76081. * @psalm-return non-empty-string
  76082. */
  76083. public function description(): string
  76084. {
  76085. return $this->description;
  76086. }
  76087. /**
  76088. * @psalm-return non-empty-array<non-empty-string, array{test: Test, count: int}>
  76089. */
  76090. public function triggeringTests(): array
  76091. {
  76092. return $this->triggeringTests;
  76093. }
  76094. }
  76095. <?php
  76096. declare (strict_types=1);
  76097. /*
  76098. * This file is part of PHPUnit.
  76099. *
  76100. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76101. *
  76102. * For the full copyright and license information, please view the LICENSE
  76103. * file that was distributed with this source code.
  76104. */
  76105. namespace PHPUnit\TestRunner\TestResult;
  76106. use function array_merge;
  76107. use function assert;
  76108. use function in_array;
  76109. use PHPUnit\Event\Code\TestMethod;
  76110. use PHPUnit\Framework\TestSize\Known;
  76111. use PHPUnit\Framework\TestSize\TestSize;
  76112. use PHPUnit\Metadata\Api\Groups;
  76113. /**
  76114. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76115. *
  76116. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76117. */
  76118. final class PassedTests
  76119. {
  76120. private static ?self $instance = null;
  76121. /**
  76122. * @psalm-var list<class-string>
  76123. */
  76124. private array $passedTestClasses = [];
  76125. /**
  76126. * @psalm-var array<string,array{returnValue: mixed, size: TestSize}>
  76127. */
  76128. private array $passedTestMethods = [];
  76129. public static function instance(): self
  76130. {
  76131. if (self::$instance !== null) {
  76132. return self::$instance;
  76133. }
  76134. self::$instance = new self();
  76135. return self::$instance;
  76136. }
  76137. /**
  76138. * @psalm-param class-string $className
  76139. */
  76140. public function testClassPassed(string $className): void
  76141. {
  76142. $this->passedTestClasses[] = $className;
  76143. }
  76144. public function testMethodPassed(TestMethod $test, mixed $returnValue): void
  76145. {
  76146. $size = (new Groups())->size($test->className(), $test->methodName());
  76147. $this->passedTestMethods[$test->className() . '::' . $test->methodName()] = ['returnValue' => $returnValue, 'size' => $size];
  76148. }
  76149. public function import(self $other): void
  76150. {
  76151. $this->passedTestClasses = array_merge($this->passedTestClasses, $other->passedTestClasses);
  76152. $this->passedTestMethods = array_merge($this->passedTestMethods, $other->passedTestMethods);
  76153. }
  76154. /**
  76155. * @psalm-param class-string $className
  76156. */
  76157. public function hasTestClassPassed(string $className): bool
  76158. {
  76159. return in_array($className, $this->passedTestClasses, \true);
  76160. }
  76161. public function hasTestMethodPassed(string $method): bool
  76162. {
  76163. return isset($this->passedTestMethods[$method]);
  76164. }
  76165. public function isGreaterThan(string $method, TestSize $other): bool
  76166. {
  76167. if ($other->isUnknown()) {
  76168. return \false;
  76169. }
  76170. assert($other instanceof Known);
  76171. $size = $this->passedTestMethods[$method]['size'];
  76172. if ($size->isUnknown()) {
  76173. return \false;
  76174. }
  76175. assert($size instanceof Known);
  76176. return $size->isGreaterThan($other);
  76177. }
  76178. public function returnValue(string $method): mixed
  76179. {
  76180. if (isset($this->passedTestMethods[$method])) {
  76181. return $this->passedTestMethods[$method]['returnValue'];
  76182. }
  76183. return null;
  76184. }
  76185. }
  76186. <?php
  76187. declare (strict_types=1);
  76188. /*
  76189. * This file is part of PHPUnit.
  76190. *
  76191. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76192. *
  76193. * For the full copyright and license information, please view the LICENSE
  76194. * file that was distributed with this source code.
  76195. */
  76196. namespace PHPUnit\TestRunner\TestResult;
  76197. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  76198. use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
  76199. /**
  76200. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76201. *
  76202. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76203. */
  76204. final class BeforeTestClassMethodErroredSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements BeforeFirstTestMethodErroredSubscriber
  76205. {
  76206. public function notify(BeforeFirstTestMethodErrored $event): void
  76207. {
  76208. $this->collector()->beforeTestClassMethodErrored($event);
  76209. }
  76210. }
  76211. <?php
  76212. declare (strict_types=1);
  76213. /*
  76214. * This file is part of PHPUnit.
  76215. *
  76216. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76217. *
  76218. * For the full copyright and license information, please view the LICENSE
  76219. * file that was distributed with this source code.
  76220. */
  76221. namespace PHPUnit\TestRunner\TestResult;
  76222. use PHPUnit\Event\TestRunner\ExecutionStarted;
  76223. use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber as TestRunnerExecutionStartedSubscriber;
  76224. /**
  76225. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76226. *
  76227. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76228. */
  76229. final class ExecutionStartedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements TestRunnerExecutionStartedSubscriber
  76230. {
  76231. public function notify(ExecutionStarted $event): void
  76232. {
  76233. $this->collector()->executionStarted($event);
  76234. }
  76235. }
  76236. <?php
  76237. declare (strict_types=1);
  76238. /*
  76239. * This file is part of PHPUnit.
  76240. *
  76241. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76242. *
  76243. * For the full copyright and license information, please view the LICENSE
  76244. * file that was distributed with this source code.
  76245. */
  76246. namespace PHPUnit\TestRunner\TestResult;
  76247. /**
  76248. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76249. *
  76250. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76251. */
  76252. abstract class Subscriber
  76253. {
  76254. private readonly \PHPUnit\TestRunner\TestResult\Collector $collector;
  76255. public function __construct(\PHPUnit\TestRunner\TestResult\Collector $collector)
  76256. {
  76257. $this->collector = $collector;
  76258. }
  76259. protected function collector(): \PHPUnit\TestRunner\TestResult\Collector
  76260. {
  76261. return $this->collector;
  76262. }
  76263. }
  76264. <?php
  76265. declare (strict_types=1);
  76266. /*
  76267. * This file is part of PHPUnit.
  76268. *
  76269. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76270. *
  76271. * For the full copyright and license information, please view the LICENSE
  76272. * file that was distributed with this source code.
  76273. */
  76274. namespace PHPUnit\TestRunner\TestResult;
  76275. use PHPUnit\Event\Test\ConsideredRisky;
  76276. use PHPUnit\Event\Test\ConsideredRiskySubscriber;
  76277. /**
  76278. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76279. *
  76280. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76281. */
  76282. final class TestConsideredRiskySubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ConsideredRiskySubscriber
  76283. {
  76284. public function notify(ConsideredRisky $event): void
  76285. {
  76286. $this->collector()->testConsideredRisky($event);
  76287. }
  76288. }
  76289. <?php
  76290. declare (strict_types=1);
  76291. /*
  76292. * This file is part of PHPUnit.
  76293. *
  76294. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76295. *
  76296. * For the full copyright and license information, please view the LICENSE
  76297. * file that was distributed with this source code.
  76298. */
  76299. namespace PHPUnit\TestRunner\TestResult;
  76300. use PHPUnit\Event\Test\Errored;
  76301. use PHPUnit\Event\Test\ErroredSubscriber;
  76302. /**
  76303. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76304. *
  76305. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76306. */
  76307. final class TestErroredSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ErroredSubscriber
  76308. {
  76309. public function notify(Errored $event): void
  76310. {
  76311. $this->collector()->testErrored($event);
  76312. }
  76313. }
  76314. <?php
  76315. declare (strict_types=1);
  76316. /*
  76317. * This file is part of PHPUnit.
  76318. *
  76319. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76320. *
  76321. * For the full copyright and license information, please view the LICENSE
  76322. * file that was distributed with this source code.
  76323. */
  76324. namespace PHPUnit\TestRunner\TestResult;
  76325. use PHPUnit\Event\Test\Failed;
  76326. use PHPUnit\Event\Test\FailedSubscriber;
  76327. /**
  76328. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76329. *
  76330. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76331. */
  76332. final class TestFailedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FailedSubscriber
  76333. {
  76334. public function notify(Failed $event): void
  76335. {
  76336. $this->collector()->testFailed($event);
  76337. }
  76338. }
  76339. <?php
  76340. declare (strict_types=1);
  76341. /*
  76342. * This file is part of PHPUnit.
  76343. *
  76344. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76345. *
  76346. * For the full copyright and license information, please view the LICENSE
  76347. * file that was distributed with this source code.
  76348. */
  76349. namespace PHPUnit\TestRunner\TestResult;
  76350. use PHPUnit\Event\Test\Finished;
  76351. use PHPUnit\Event\Test\FinishedSubscriber;
  76352. /**
  76353. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76354. *
  76355. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76356. */
  76357. final class TestFinishedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FinishedSubscriber
  76358. {
  76359. public function notify(Finished $event): void
  76360. {
  76361. $this->collector()->testFinished($event);
  76362. }
  76363. }
  76364. <?php
  76365. declare (strict_types=1);
  76366. /*
  76367. * This file is part of PHPUnit.
  76368. *
  76369. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76370. *
  76371. * For the full copyright and license information, please view the LICENSE
  76372. * file that was distributed with this source code.
  76373. */
  76374. namespace PHPUnit\TestRunner\TestResult;
  76375. use PHPUnit\Event\Test\MarkedIncomplete;
  76376. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  76377. /**
  76378. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76379. *
  76380. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76381. */
  76382. final class TestMarkedIncompleteSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements MarkedIncompleteSubscriber
  76383. {
  76384. public function notify(MarkedIncomplete $event): void
  76385. {
  76386. $this->collector()->testMarkedIncomplete($event);
  76387. }
  76388. }
  76389. <?php
  76390. declare (strict_types=1);
  76391. /*
  76392. * This file is part of PHPUnit.
  76393. *
  76394. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76395. *
  76396. * For the full copyright and license information, please view the LICENSE
  76397. * file that was distributed with this source code.
  76398. */
  76399. namespace PHPUnit\TestRunner\TestResult;
  76400. use PHPUnit\Event\Test\Prepared;
  76401. use PHPUnit\Event\Test\PreparedSubscriber;
  76402. /**
  76403. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76404. *
  76405. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76406. */
  76407. final class TestPreparedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PreparedSubscriber
  76408. {
  76409. public function notify(Prepared $event): void
  76410. {
  76411. $this->collector()->testPrepared();
  76412. }
  76413. }
  76414. <?php
  76415. declare (strict_types=1);
  76416. /*
  76417. * This file is part of PHPUnit.
  76418. *
  76419. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76420. *
  76421. * For the full copyright and license information, please view the LICENSE
  76422. * file that was distributed with this source code.
  76423. */
  76424. namespace PHPUnit\TestRunner\TestResult;
  76425. use PHPUnit\Event\TestRunner\DeprecationTriggered;
  76426. use PHPUnit\Event\TestRunner\DeprecationTriggeredSubscriber;
  76427. /**
  76428. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76429. *
  76430. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76431. */
  76432. final class TestRunnerTriggeredDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements DeprecationTriggeredSubscriber
  76433. {
  76434. public function notify(DeprecationTriggered $event): void
  76435. {
  76436. $this->collector()->testRunnerTriggeredDeprecation($event);
  76437. }
  76438. }
  76439. <?php
  76440. declare (strict_types=1);
  76441. /*
  76442. * This file is part of PHPUnit.
  76443. *
  76444. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76445. *
  76446. * For the full copyright and license information, please view the LICENSE
  76447. * file that was distributed with this source code.
  76448. */
  76449. namespace PHPUnit\TestRunner\TestResult;
  76450. use PHPUnit\Event\TestRunner\WarningTriggered;
  76451. use PHPUnit\Event\TestRunner\WarningTriggeredSubscriber;
  76452. /**
  76453. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76454. *
  76455. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76456. */
  76457. final class TestRunnerTriggeredWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements WarningTriggeredSubscriber
  76458. {
  76459. public function notify(WarningTriggered $event): void
  76460. {
  76461. $this->collector()->testRunnerTriggeredWarning($event);
  76462. }
  76463. }
  76464. <?php
  76465. declare (strict_types=1);
  76466. /*
  76467. * This file is part of PHPUnit.
  76468. *
  76469. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76470. *
  76471. * For the full copyright and license information, please view the LICENSE
  76472. * file that was distributed with this source code.
  76473. */
  76474. namespace PHPUnit\TestRunner\TestResult;
  76475. use PHPUnit\Event\Test\Skipped;
  76476. use PHPUnit\Event\Test\SkippedSubscriber;
  76477. /**
  76478. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76479. *
  76480. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76481. */
  76482. final class TestSkippedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements SkippedSubscriber
  76483. {
  76484. public function notify(Skipped $event): void
  76485. {
  76486. $this->collector()->testSkipped($event);
  76487. }
  76488. }
  76489. <?php
  76490. declare (strict_types=1);
  76491. /*
  76492. * This file is part of PHPUnit.
  76493. *
  76494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76495. *
  76496. * For the full copyright and license information, please view the LICENSE
  76497. * file that was distributed with this source code.
  76498. */
  76499. namespace PHPUnit\TestRunner\TestResult;
  76500. use PHPUnit\Event\TestSuite\Finished;
  76501. use PHPUnit\Event\TestSuite\FinishedSubscriber;
  76502. /**
  76503. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76504. *
  76505. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76506. */
  76507. final class TestSuiteFinishedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FinishedSubscriber
  76508. {
  76509. public function notify(Finished $event): void
  76510. {
  76511. $this->collector()->testSuiteFinished($event);
  76512. }
  76513. }
  76514. <?php
  76515. declare (strict_types=1);
  76516. /*
  76517. * This file is part of PHPUnit.
  76518. *
  76519. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76520. *
  76521. * For the full copyright and license information, please view the LICENSE
  76522. * file that was distributed with this source code.
  76523. */
  76524. namespace PHPUnit\TestRunner\TestResult;
  76525. use PHPUnit\Event\TestSuite\Skipped;
  76526. use PHPUnit\Event\TestSuite\SkippedSubscriber;
  76527. /**
  76528. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76529. *
  76530. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76531. */
  76532. final class TestSuiteSkippedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements SkippedSubscriber
  76533. {
  76534. public function notify(Skipped $event): void
  76535. {
  76536. $this->collector()->testSuiteSkipped($event);
  76537. }
  76538. }
  76539. <?php
  76540. declare (strict_types=1);
  76541. /*
  76542. * This file is part of PHPUnit.
  76543. *
  76544. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76545. *
  76546. * For the full copyright and license information, please view the LICENSE
  76547. * file that was distributed with this source code.
  76548. */
  76549. namespace PHPUnit\TestRunner\TestResult;
  76550. use PHPUnit\Event\TestSuite\Started;
  76551. use PHPUnit\Event\TestSuite\StartedSubscriber;
  76552. /**
  76553. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76554. *
  76555. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76556. */
  76557. final class TestSuiteStartedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements StartedSubscriber
  76558. {
  76559. public function notify(Started $event): void
  76560. {
  76561. $this->collector()->testSuiteStarted($event);
  76562. }
  76563. }
  76564. <?php
  76565. declare (strict_types=1);
  76566. /*
  76567. * This file is part of PHPUnit.
  76568. *
  76569. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76570. *
  76571. * For the full copyright and license information, please view the LICENSE
  76572. * file that was distributed with this source code.
  76573. */
  76574. namespace PHPUnit\TestRunner\TestResult;
  76575. use PHPUnit\Event\Test\DeprecationTriggered;
  76576. use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
  76577. /**
  76578. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76579. *
  76580. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76581. */
  76582. final class TestTriggeredDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements DeprecationTriggeredSubscriber
  76583. {
  76584. public function notify(DeprecationTriggered $event): void
  76585. {
  76586. $this->collector()->testTriggeredDeprecation($event);
  76587. }
  76588. }
  76589. <?php
  76590. declare (strict_types=1);
  76591. /*
  76592. * This file is part of PHPUnit.
  76593. *
  76594. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76595. *
  76596. * For the full copyright and license information, please view the LICENSE
  76597. * file that was distributed with this source code.
  76598. */
  76599. namespace PHPUnit\TestRunner\TestResult;
  76600. use PHPUnit\Event\Test\ErrorTriggered;
  76601. use PHPUnit\Event\Test\ErrorTriggeredSubscriber;
  76602. /**
  76603. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76604. *
  76605. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76606. */
  76607. final class TestTriggeredErrorSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ErrorTriggeredSubscriber
  76608. {
  76609. public function notify(ErrorTriggered $event): void
  76610. {
  76611. $this->collector()->testTriggeredError($event);
  76612. }
  76613. }
  76614. <?php
  76615. declare (strict_types=1);
  76616. /*
  76617. * This file is part of PHPUnit.
  76618. *
  76619. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76620. *
  76621. * For the full copyright and license information, please view the LICENSE
  76622. * file that was distributed with this source code.
  76623. */
  76624. namespace PHPUnit\TestRunner\TestResult;
  76625. use PHPUnit\Event\Test\NoticeTriggered;
  76626. use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
  76627. /**
  76628. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76629. *
  76630. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76631. */
  76632. final class TestTriggeredNoticeSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements NoticeTriggeredSubscriber
  76633. {
  76634. public function notify(NoticeTriggered $event): void
  76635. {
  76636. $this->collector()->testTriggeredNotice($event);
  76637. }
  76638. }
  76639. <?php
  76640. declare (strict_types=1);
  76641. /*
  76642. * This file is part of PHPUnit.
  76643. *
  76644. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76645. *
  76646. * For the full copyright and license information, please view the LICENSE
  76647. * file that was distributed with this source code.
  76648. */
  76649. namespace PHPUnit\TestRunner\TestResult;
  76650. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  76651. use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
  76652. /**
  76653. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76654. *
  76655. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76656. */
  76657. final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpDeprecationTriggeredSubscriber
  76658. {
  76659. public function notify(PhpDeprecationTriggered $event): void
  76660. {
  76661. $this->collector()->testTriggeredPhpDeprecation($event);
  76662. }
  76663. }
  76664. <?php
  76665. declare (strict_types=1);
  76666. /*
  76667. * This file is part of PHPUnit.
  76668. *
  76669. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76670. *
  76671. * For the full copyright and license information, please view the LICENSE
  76672. * file that was distributed with this source code.
  76673. */
  76674. namespace PHPUnit\TestRunner\TestResult;
  76675. use PHPUnit\Event\Test\PhpNoticeTriggered;
  76676. use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
  76677. /**
  76678. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76679. *
  76680. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76681. */
  76682. final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpNoticeTriggeredSubscriber
  76683. {
  76684. public function notify(PhpNoticeTriggered $event): void
  76685. {
  76686. $this->collector()->testTriggeredPhpNotice($event);
  76687. }
  76688. }
  76689. <?php
  76690. declare (strict_types=1);
  76691. /*
  76692. * This file is part of PHPUnit.
  76693. *
  76694. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76695. *
  76696. * For the full copyright and license information, please view the LICENSE
  76697. * file that was distributed with this source code.
  76698. */
  76699. namespace PHPUnit\TestRunner\TestResult;
  76700. use PHPUnit\Event\Test\PhpWarningTriggered;
  76701. use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
  76702. /**
  76703. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76704. *
  76705. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76706. */
  76707. final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpWarningTriggeredSubscriber
  76708. {
  76709. public function notify(PhpWarningTriggered $event): void
  76710. {
  76711. $this->collector()->testTriggeredPhpWarning($event);
  76712. }
  76713. }
  76714. <?php
  76715. declare (strict_types=1);
  76716. /*
  76717. * This file is part of PHPUnit.
  76718. *
  76719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76720. *
  76721. * For the full copyright and license information, please view the LICENSE
  76722. * file that was distributed with this source code.
  76723. */
  76724. namespace PHPUnit\TestRunner\TestResult;
  76725. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  76726. use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
  76727. /**
  76728. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76729. *
  76730. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76731. */
  76732. final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitDeprecationTriggeredSubscriber
  76733. {
  76734. public function notify(PhpunitDeprecationTriggered $event): void
  76735. {
  76736. $this->collector()->testTriggeredPhpunitDeprecation($event);
  76737. }
  76738. }
  76739. <?php
  76740. declare (strict_types=1);
  76741. /*
  76742. * This file is part of PHPUnit.
  76743. *
  76744. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76745. *
  76746. * For the full copyright and license information, please view the LICENSE
  76747. * file that was distributed with this source code.
  76748. */
  76749. namespace PHPUnit\TestRunner\TestResult;
  76750. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  76751. use PHPUnit\Event\Test\PhpunitErrorTriggeredSubscriber;
  76752. /**
  76753. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76754. *
  76755. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76756. */
  76757. final class TestTriggeredPhpunitErrorSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitErrorTriggeredSubscriber
  76758. {
  76759. public function notify(PhpunitErrorTriggered $event): void
  76760. {
  76761. $this->collector()->testTriggeredPhpunitError($event);
  76762. }
  76763. }
  76764. <?php
  76765. declare (strict_types=1);
  76766. /*
  76767. * This file is part of PHPUnit.
  76768. *
  76769. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76770. *
  76771. * For the full copyright and license information, please view the LICENSE
  76772. * file that was distributed with this source code.
  76773. */
  76774. namespace PHPUnit\TestRunner\TestResult;
  76775. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  76776. use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
  76777. /**
  76778. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76779. *
  76780. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76781. */
  76782. final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitWarningTriggeredSubscriber
  76783. {
  76784. public function notify(PhpunitWarningTriggered $event): void
  76785. {
  76786. $this->collector()->testTriggeredPhpunitWarning($event);
  76787. }
  76788. }
  76789. <?php
  76790. declare (strict_types=1);
  76791. /*
  76792. * This file is part of PHPUnit.
  76793. *
  76794. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76795. *
  76796. * For the full copyright and license information, please view the LICENSE
  76797. * file that was distributed with this source code.
  76798. */
  76799. namespace PHPUnit\TestRunner\TestResult;
  76800. use PHPUnit\Event\Test\WarningTriggered;
  76801. use PHPUnit\Event\Test\WarningTriggeredSubscriber;
  76802. /**
  76803. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76804. *
  76805. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76806. */
  76807. final class TestTriggeredWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements WarningTriggeredSubscriber
  76808. {
  76809. public function notify(WarningTriggered $event): void
  76810. {
  76811. $this->collector()->testTriggeredWarning($event);
  76812. }
  76813. }
  76814. <?php
  76815. declare (strict_types=1);
  76816. /*
  76817. * This file is part of PHPUnit.
  76818. *
  76819. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  76820. *
  76821. * For the full copyright and license information, please view the LICENSE
  76822. * file that was distributed with this source code.
  76823. */
  76824. namespace PHPUnit\TestRunner\TestResult;
  76825. use function count;
  76826. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  76827. use PHPUnit\Event\Test\ConsideredRisky;
  76828. use PHPUnit\Event\Test\Errored;
  76829. use PHPUnit\Event\Test\Failed;
  76830. use PHPUnit\Event\Test\MarkedIncomplete;
  76831. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  76832. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  76833. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  76834. use PHPUnit\Event\Test\Skipped as TestSkipped;
  76835. use PHPUnit\Event\TestRunner\DeprecationTriggered as TestRunnerDeprecationTriggered;
  76836. use PHPUnit\Event\TestRunner\WarningTriggered as TestRunnerWarningTriggered;
  76837. use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
  76838. use PHPUnit\TestRunner\TestResult\Issues\Issue;
  76839. /**
  76840. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  76841. *
  76842. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  76843. */
  76844. final class TestResult
  76845. {
  76846. private readonly int $numberOfTests;
  76847. private readonly int $numberOfTestsRun;
  76848. private readonly int $numberOfAssertions;
  76849. /**
  76850. * @psalm-var list<BeforeFirstTestMethodErrored|Errored>
  76851. */
  76852. private readonly array $testErroredEvents;
  76853. /**
  76854. * @psalm-var list<Failed>
  76855. */
  76856. private readonly array $testFailedEvents;
  76857. /**
  76858. * @psalm-var list<MarkedIncomplete>
  76859. */
  76860. private readonly array $testMarkedIncompleteEvents;
  76861. /**
  76862. * @psalm-var list<TestSuiteSkipped>
  76863. */
  76864. private readonly array $testSuiteSkippedEvents;
  76865. /**
  76866. * @psalm-var list<TestSkipped>
  76867. */
  76868. private readonly array $testSkippedEvents;
  76869. /**
  76870. * @psalm-var array<string,list<ConsideredRisky>>
  76871. */
  76872. private readonly array $testConsideredRiskyEvents;
  76873. /**
  76874. * @psalm-var array<string,list<PhpunitDeprecationTriggered>>
  76875. */
  76876. private readonly array $testTriggeredPhpunitDeprecationEvents;
  76877. /**
  76878. * @psalm-var array<string,list<PhpunitErrorTriggered>>
  76879. */
  76880. private readonly array $testTriggeredPhpunitErrorEvents;
  76881. /**
  76882. * @psalm-var array<string,list<PhpunitWarningTriggered>>
  76883. */
  76884. private readonly array $testTriggeredPhpunitWarningEvents;
  76885. /**
  76886. * @psalm-var list<TestRunnerDeprecationTriggered>
  76887. */
  76888. private readonly array $testRunnerTriggeredDeprecationEvents;
  76889. /**
  76890. * @psalm-var list<TestRunnerWarningTriggered>
  76891. */
  76892. private readonly array $testRunnerTriggeredWarningEvents;
  76893. /**
  76894. * @psalm-var list<Issue>
  76895. */
  76896. private readonly array $errors;
  76897. /**
  76898. * @psalm-var list<Issue>
  76899. */
  76900. private readonly array $deprecations;
  76901. /**
  76902. * @psalm-var list<Issue>
  76903. */
  76904. private readonly array $notices;
  76905. /**
  76906. * @psalm-var list<Issue>
  76907. */
  76908. private readonly array $warnings;
  76909. /**
  76910. * @psalm-var list<Issue>
  76911. */
  76912. private readonly array $phpDeprecations;
  76913. /**
  76914. * @psalm-var list<Issue>
  76915. */
  76916. private readonly array $phpNotices;
  76917. /**
  76918. * @psalm-var list<Issue>
  76919. */
  76920. private readonly array $phpWarnings;
  76921. /**
  76922. * @psalm-var non-negative-int
  76923. */
  76924. private readonly int $numberOfIssuesIgnoredByBaseline;
  76925. /**
  76926. * @psalm-param list<BeforeFirstTestMethodErrored|Errored> $testErroredEvents
  76927. * @psalm-param list<Failed> $testFailedEvents
  76928. * @psalm-param array<string,list<ConsideredRisky>> $testConsideredRiskyEvents
  76929. * @psalm-param list<TestSuiteSkipped> $testSuiteSkippedEvents
  76930. * @psalm-param list<TestSkipped> $testSkippedEvents
  76931. * @psalm-param list<MarkedIncomplete> $testMarkedIncompleteEvents
  76932. * @psalm-param array<string,list<PhpunitDeprecationTriggered>> $testTriggeredPhpunitDeprecationEvents
  76933. * @psalm-param array<string,list<PhpunitErrorTriggered>> $testTriggeredPhpunitErrorEvents
  76934. * @psalm-param array<string,list<PhpunitWarningTriggered>> $testTriggeredPhpunitWarningEvents
  76935. * @psalm-param list<TestRunnerDeprecationTriggered> $testRunnerTriggeredDeprecationEvents
  76936. * @psalm-param list<TestRunnerWarningTriggered> $testRunnerTriggeredWarningEvents
  76937. * @psalm-param list<Issue> $errors
  76938. * @psalm-param list<Issue> $deprecations
  76939. * @psalm-param list<Issue> $notices
  76940. * @psalm-param list<Issue> $warnings
  76941. * @psalm-param list<Issue> $phpDeprecations
  76942. * @psalm-param list<Issue> $phpNotices
  76943. * @psalm-param list<Issue> $phpWarnings
  76944. * @psalm-param non-negative-int $numberOfIssuesIgnoredByBaseline
  76945. */
  76946. public function __construct(int $numberOfTests, int $numberOfTestsRun, int $numberOfAssertions, array $testErroredEvents, array $testFailedEvents, array $testConsideredRiskyEvents, array $testSuiteSkippedEvents, array $testSkippedEvents, array $testMarkedIncompleteEvents, array $testTriggeredPhpunitDeprecationEvents, array $testTriggeredPhpunitErrorEvents, array $testTriggeredPhpunitWarningEvents, array $testRunnerTriggeredDeprecationEvents, array $testRunnerTriggeredWarningEvents, array $errors, array $deprecations, array $notices, array $warnings, array $phpDeprecations, array $phpNotices, array $phpWarnings, int $numberOfIssuesIgnoredByBaseline)
  76947. {
  76948. $this->numberOfTests = $numberOfTests;
  76949. $this->numberOfTestsRun = $numberOfTestsRun;
  76950. $this->numberOfAssertions = $numberOfAssertions;
  76951. $this->testErroredEvents = $testErroredEvents;
  76952. $this->testFailedEvents = $testFailedEvents;
  76953. $this->testConsideredRiskyEvents = $testConsideredRiskyEvents;
  76954. $this->testSuiteSkippedEvents = $testSuiteSkippedEvents;
  76955. $this->testSkippedEvents = $testSkippedEvents;
  76956. $this->testMarkedIncompleteEvents = $testMarkedIncompleteEvents;
  76957. $this->testTriggeredPhpunitDeprecationEvents = $testTriggeredPhpunitDeprecationEvents;
  76958. $this->testTriggeredPhpunitErrorEvents = $testTriggeredPhpunitErrorEvents;
  76959. $this->testTriggeredPhpunitWarningEvents = $testTriggeredPhpunitWarningEvents;
  76960. $this->testRunnerTriggeredDeprecationEvents = $testRunnerTriggeredDeprecationEvents;
  76961. $this->testRunnerTriggeredWarningEvents = $testRunnerTriggeredWarningEvents;
  76962. $this->errors = $errors;
  76963. $this->deprecations = $deprecations;
  76964. $this->notices = $notices;
  76965. $this->warnings = $warnings;
  76966. $this->phpDeprecations = $phpDeprecations;
  76967. $this->phpNotices = $phpNotices;
  76968. $this->phpWarnings = $phpWarnings;
  76969. $this->numberOfIssuesIgnoredByBaseline = $numberOfIssuesIgnoredByBaseline;
  76970. }
  76971. public function numberOfTestsRun(): int
  76972. {
  76973. return $this->numberOfTestsRun;
  76974. }
  76975. public function numberOfAssertions(): int
  76976. {
  76977. return $this->numberOfAssertions;
  76978. }
  76979. /**
  76980. * @psalm-return list<BeforeFirstTestMethodErrored|Errored>
  76981. */
  76982. public function testErroredEvents(): array
  76983. {
  76984. return $this->testErroredEvents;
  76985. }
  76986. public function numberOfTestErroredEvents(): int
  76987. {
  76988. return count($this->testErroredEvents);
  76989. }
  76990. public function hasTestErroredEvents(): bool
  76991. {
  76992. return $this->numberOfTestErroredEvents() > 0;
  76993. }
  76994. /**
  76995. * @psalm-return list<Failed>
  76996. */
  76997. public function testFailedEvents(): array
  76998. {
  76999. return $this->testFailedEvents;
  77000. }
  77001. public function numberOfTestFailedEvents(): int
  77002. {
  77003. return count($this->testFailedEvents);
  77004. }
  77005. public function hasTestFailedEvents(): bool
  77006. {
  77007. return $this->numberOfTestFailedEvents() > 0;
  77008. }
  77009. /**
  77010. * @psalm-return array<string,list<ConsideredRisky>>
  77011. */
  77012. public function testConsideredRiskyEvents(): array
  77013. {
  77014. return $this->testConsideredRiskyEvents;
  77015. }
  77016. public function numberOfTestsWithTestConsideredRiskyEvents(): int
  77017. {
  77018. return count($this->testConsideredRiskyEvents);
  77019. }
  77020. public function hasTestConsideredRiskyEvents(): bool
  77021. {
  77022. return $this->numberOfTestsWithTestConsideredRiskyEvents() > 0;
  77023. }
  77024. /**
  77025. * @psalm-return list<TestSuiteSkipped>
  77026. */
  77027. public function testSuiteSkippedEvents(): array
  77028. {
  77029. return $this->testSuiteSkippedEvents;
  77030. }
  77031. public function numberOfTestSuiteSkippedEvents(): int
  77032. {
  77033. return count($this->testSuiteSkippedEvents);
  77034. }
  77035. public function hasTestSuiteSkippedEvents(): bool
  77036. {
  77037. return $this->numberOfTestSuiteSkippedEvents() > 0;
  77038. }
  77039. /**
  77040. * @psalm-return list<TestSkipped>
  77041. */
  77042. public function testSkippedEvents(): array
  77043. {
  77044. return $this->testSkippedEvents;
  77045. }
  77046. public function numberOfTestSkippedEvents(): int
  77047. {
  77048. return count($this->testSkippedEvents);
  77049. }
  77050. public function hasTestSkippedEvents(): bool
  77051. {
  77052. return $this->numberOfTestSkippedEvents() > 0;
  77053. }
  77054. /**
  77055. * @psalm-return list<MarkedIncomplete>
  77056. */
  77057. public function testMarkedIncompleteEvents(): array
  77058. {
  77059. return $this->testMarkedIncompleteEvents;
  77060. }
  77061. public function numberOfTestMarkedIncompleteEvents(): int
  77062. {
  77063. return count($this->testMarkedIncompleteEvents);
  77064. }
  77065. public function hasTestMarkedIncompleteEvents(): bool
  77066. {
  77067. return $this->numberOfTestMarkedIncompleteEvents() > 0;
  77068. }
  77069. /**
  77070. * @psalm-return array<string,list<PhpunitDeprecationTriggered>>
  77071. */
  77072. public function testTriggeredPhpunitDeprecationEvents(): array
  77073. {
  77074. return $this->testTriggeredPhpunitDeprecationEvents;
  77075. }
  77076. public function numberOfTestsWithTestTriggeredPhpunitDeprecationEvents(): int
  77077. {
  77078. return count($this->testTriggeredPhpunitDeprecationEvents);
  77079. }
  77080. public function hasTestTriggeredPhpunitDeprecationEvents(): bool
  77081. {
  77082. return $this->numberOfTestsWithTestTriggeredPhpunitDeprecationEvents() > 0;
  77083. }
  77084. /**
  77085. * @psalm-return array<string,list<PhpunitErrorTriggered>>
  77086. */
  77087. public function testTriggeredPhpunitErrorEvents(): array
  77088. {
  77089. return $this->testTriggeredPhpunitErrorEvents;
  77090. }
  77091. public function numberOfTestsWithTestTriggeredPhpunitErrorEvents(): int
  77092. {
  77093. return count($this->testTriggeredPhpunitErrorEvents);
  77094. }
  77095. public function hasTestTriggeredPhpunitErrorEvents(): bool
  77096. {
  77097. return $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents() > 0;
  77098. }
  77099. /**
  77100. * @psalm-return array<string,list<PhpunitWarningTriggered>>
  77101. */
  77102. public function testTriggeredPhpunitWarningEvents(): array
  77103. {
  77104. return $this->testTriggeredPhpunitWarningEvents;
  77105. }
  77106. public function numberOfTestsWithTestTriggeredPhpunitWarningEvents(): int
  77107. {
  77108. return count($this->testTriggeredPhpunitWarningEvents);
  77109. }
  77110. public function hasTestTriggeredPhpunitWarningEvents(): bool
  77111. {
  77112. return $this->numberOfTestsWithTestTriggeredPhpunitWarningEvents() > 0;
  77113. }
  77114. /**
  77115. * @psalm-return list<TestRunnerDeprecationTriggered>
  77116. */
  77117. public function testRunnerTriggeredDeprecationEvents(): array
  77118. {
  77119. return $this->testRunnerTriggeredDeprecationEvents;
  77120. }
  77121. public function numberOfTestRunnerTriggeredDeprecationEvents(): int
  77122. {
  77123. return count($this->testRunnerTriggeredDeprecationEvents);
  77124. }
  77125. public function hasTestRunnerTriggeredDeprecationEvents(): bool
  77126. {
  77127. return $this->numberOfTestRunnerTriggeredDeprecationEvents() > 0;
  77128. }
  77129. /**
  77130. * @psalm-return list<TestRunnerWarningTriggered>
  77131. */
  77132. public function testRunnerTriggeredWarningEvents(): array
  77133. {
  77134. return $this->testRunnerTriggeredWarningEvents;
  77135. }
  77136. public function numberOfTestRunnerTriggeredWarningEvents(): int
  77137. {
  77138. return count($this->testRunnerTriggeredWarningEvents);
  77139. }
  77140. public function hasTestRunnerTriggeredWarningEvents(): bool
  77141. {
  77142. return $this->numberOfTestRunnerTriggeredWarningEvents() > 0;
  77143. }
  77144. public function wasSuccessful(): bool
  77145. {
  77146. return $this->wasSuccessfulIgnoringPhpunitWarnings() && !$this->hasTestTriggeredPhpunitErrorEvents() && !$this->hasTestRunnerTriggeredWarningEvents() && !$this->hasTestTriggeredPhpunitWarningEvents();
  77147. }
  77148. public function wasSuccessfulIgnoringPhpunitWarnings(): bool
  77149. {
  77150. return !$this->hasTestErroredEvents() && !$this->hasTestFailedEvents();
  77151. }
  77152. public function wasSuccessfulAndNoTestHasIssues(): bool
  77153. {
  77154. return $this->wasSuccessful() && !$this->hasTestsWithIssues();
  77155. }
  77156. public function hasTestsWithIssues(): bool
  77157. {
  77158. return $this->hasRiskyTests() || $this->hasIncompleteTests() || $this->hasDeprecations() || !empty($this->errors) || $this->hasNotices() || $this->hasWarnings();
  77159. }
  77160. /**
  77161. * @psalm-return list<Issue>
  77162. */
  77163. public function errors(): array
  77164. {
  77165. return $this->errors;
  77166. }
  77167. /**
  77168. * @psalm-return list<Issue>
  77169. */
  77170. public function deprecations(): array
  77171. {
  77172. return $this->deprecations;
  77173. }
  77174. /**
  77175. * @psalm-return list<Issue>
  77176. */
  77177. public function notices(): array
  77178. {
  77179. return $this->notices;
  77180. }
  77181. /**
  77182. * @psalm-return list<Issue>
  77183. */
  77184. public function warnings(): array
  77185. {
  77186. return $this->warnings;
  77187. }
  77188. /**
  77189. * @psalm-return list<Issue>
  77190. */
  77191. public function phpDeprecations(): array
  77192. {
  77193. return $this->phpDeprecations;
  77194. }
  77195. /**
  77196. * @psalm-return list<Issue>
  77197. */
  77198. public function phpNotices(): array
  77199. {
  77200. return $this->phpNotices;
  77201. }
  77202. /**
  77203. * @psalm-return list<Issue>
  77204. */
  77205. public function phpWarnings(): array
  77206. {
  77207. return $this->phpWarnings;
  77208. }
  77209. public function hasTests(): bool
  77210. {
  77211. return $this->numberOfTests > 0;
  77212. }
  77213. public function hasErrors(): bool
  77214. {
  77215. return $this->numberOfErrors() > 0;
  77216. }
  77217. public function numberOfErrors(): int
  77218. {
  77219. return $this->numberOfTestErroredEvents() + count($this->errors) + $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents();
  77220. }
  77221. public function hasDeprecations(): bool
  77222. {
  77223. return $this->numberOfDeprecations() > 0;
  77224. }
  77225. public function hasPhpOrUserDeprecations(): bool
  77226. {
  77227. return $this->numberOfPhpOrUserDeprecations() > 0;
  77228. }
  77229. public function numberOfPhpOrUserDeprecations(): int
  77230. {
  77231. return count($this->deprecations) + count($this->phpDeprecations);
  77232. }
  77233. public function hasPhpunitDeprecations(): bool
  77234. {
  77235. return $this->numberOfPhpunitDeprecations() > 0;
  77236. }
  77237. public function numberOfPhpunitDeprecations(): int
  77238. {
  77239. return count($this->testTriggeredPhpunitDeprecationEvents) + count($this->testRunnerTriggeredDeprecationEvents);
  77240. }
  77241. public function numberOfDeprecations(): int
  77242. {
  77243. return count($this->deprecations) + count($this->phpDeprecations) + count($this->testTriggeredPhpunitDeprecationEvents) + count($this->testRunnerTriggeredDeprecationEvents);
  77244. }
  77245. public function hasNotices(): bool
  77246. {
  77247. return $this->numberOfNotices() > 0;
  77248. }
  77249. public function numberOfNotices(): int
  77250. {
  77251. return count($this->notices) + count($this->phpNotices);
  77252. }
  77253. public function hasWarnings(): bool
  77254. {
  77255. return $this->numberOfWarnings() > 0;
  77256. }
  77257. public function numberOfWarnings(): int
  77258. {
  77259. return count($this->warnings) + count($this->phpWarnings) + count($this->testTriggeredPhpunitWarningEvents) + count($this->testRunnerTriggeredWarningEvents);
  77260. }
  77261. public function hasIncompleteTests(): bool
  77262. {
  77263. return !empty($this->testMarkedIncompleteEvents);
  77264. }
  77265. public function hasRiskyTests(): bool
  77266. {
  77267. return !empty($this->testConsideredRiskyEvents);
  77268. }
  77269. public function hasSkippedTests(): bool
  77270. {
  77271. return !empty($this->testSkippedEvents);
  77272. }
  77273. public function hasIssuesIgnoredByBaseline(): bool
  77274. {
  77275. return $this->numberOfIssuesIgnoredByBaseline > 0;
  77276. }
  77277. /**
  77278. * @psalm-return non-negative-int
  77279. */
  77280. public function numberOfIssuesIgnoredByBaseline(): int
  77281. {
  77282. return $this->numberOfIssuesIgnoredByBaseline;
  77283. }
  77284. }
  77285. <?php
  77286. declare (strict_types=1);
  77287. /*
  77288. * This file is part of PHPUnit.
  77289. *
  77290. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  77291. *
  77292. * For the full copyright and license information, please view the LICENSE
  77293. * file that was distributed with this source code.
  77294. */
  77295. namespace PHPUnit\Runner;
  77296. use function array_diff;
  77297. use function array_values;
  77298. use function basename;
  77299. use function get_declared_classes;
  77300. use function realpath;
  77301. use function str_ends_with;
  77302. use function strpos;
  77303. use function strtolower;
  77304. use function substr;
  77305. use PHPUnit\Framework\TestCase;
  77306. use ReflectionClass;
  77307. /**
  77308. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  77309. *
  77310. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  77311. */
  77312. final class TestSuiteLoader
  77313. {
  77314. /**
  77315. * @psalm-var list<class-string>
  77316. */
  77317. private static array $declaredClasses = [];
  77318. /**
  77319. * @psalm-var array<non-empty-string, list<class-string>>
  77320. */
  77321. private static array $fileToClassesMap = [];
  77322. /**
  77323. * @throws Exception
  77324. */
  77325. public function load(string $suiteClassFile): ReflectionClass
  77326. {
  77327. $suiteClassFile = realpath($suiteClassFile);
  77328. $suiteClassName = $this->classNameFromFileName($suiteClassFile);
  77329. $loadedClasses = $this->loadSuiteClassFile($suiteClassFile);
  77330. foreach ($loadedClasses as $className) {
  77331. /** @noinspection PhpUnhandledExceptionInspection */
  77332. $class = new ReflectionClass($className);
  77333. if ($class->isAnonymous()) {
  77334. continue;
  77335. }
  77336. if ($class->getFileName() !== $suiteClassFile) {
  77337. continue;
  77338. }
  77339. if (!$class->isSubclassOf(TestCase::class)) {
  77340. continue;
  77341. }
  77342. if (!str_ends_with(strtolower($class->getShortName()), strtolower($suiteClassName))) {
  77343. continue;
  77344. }
  77345. if (!$class->isAbstract()) {
  77346. return $class;
  77347. }
  77348. $e = new \PHPUnit\Runner\ClassIsAbstractException($class->getName(), $suiteClassFile);
  77349. }
  77350. if (isset($e)) {
  77351. throw $e;
  77352. }
  77353. foreach ($loadedClasses as $className) {
  77354. if (str_ends_with(strtolower($className), strtolower($suiteClassName))) {
  77355. throw new \PHPUnit\Runner\ClassDoesNotExtendTestCaseException($className, $suiteClassFile);
  77356. }
  77357. }
  77358. throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile);
  77359. }
  77360. private function classNameFromFileName(string $suiteClassFile): string
  77361. {
  77362. $className = basename($suiteClassFile, '.php');
  77363. $dotPos = strpos($className, '.');
  77364. if ($dotPos !== \false) {
  77365. $className = substr($className, 0, $dotPos);
  77366. }
  77367. return $className;
  77368. }
  77369. /**
  77370. * @psalm-return list<class-string>
  77371. */
  77372. private function loadSuiteClassFile(string $suiteClassFile): array
  77373. {
  77374. if (isset(self::$fileToClassesMap[$suiteClassFile])) {
  77375. return self::$fileToClassesMap[$suiteClassFile];
  77376. }
  77377. if (empty(self::$declaredClasses)) {
  77378. self::$declaredClasses = get_declared_classes();
  77379. }
  77380. require_once $suiteClassFile;
  77381. $loadedClasses = array_values(array_diff(get_declared_classes(), self::$declaredClasses));
  77382. foreach ($loadedClasses as $loadedClass) {
  77383. /** @noinspection PhpUnhandledExceptionInspection */
  77384. $class = new ReflectionClass($loadedClass);
  77385. if (!isset(self::$fileToClassesMap[$class->getFileName()])) {
  77386. self::$fileToClassesMap[$class->getFileName()] = [];
  77387. }
  77388. self::$fileToClassesMap[$class->getFileName()][] = $class->getName();
  77389. }
  77390. self::$declaredClasses = get_declared_classes();
  77391. if (empty($loadedClasses)) {
  77392. return self::$declaredClasses;
  77393. }
  77394. return $loadedClasses;
  77395. }
  77396. }
  77397. <?php
  77398. declare (strict_types=1);
  77399. /*
  77400. * This file is part of PHPUnit.
  77401. *
  77402. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  77403. *
  77404. * For the full copyright and license information, please view the LICENSE
  77405. * file that was distributed with this source code.
  77406. */
  77407. namespace PHPUnit\Runner;
  77408. use function array_diff;
  77409. use function array_merge;
  77410. use function array_reverse;
  77411. use function array_splice;
  77412. use function count;
  77413. use function in_array;
  77414. use function max;
  77415. use function shuffle;
  77416. use function usort;
  77417. use PHPUnit\Framework\DataProviderTestSuite;
  77418. use PHPUnit\Framework\Reorderable;
  77419. use PHPUnit\Framework\Test;
  77420. use PHPUnit\Framework\TestCase;
  77421. use PHPUnit\Framework\TestSuite;
  77422. use PHPUnit\Runner\ResultCache\NullResultCache;
  77423. use PHPUnit\Runner\ResultCache\ResultCache;
  77424. /**
  77425. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  77426. *
  77427. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  77428. */
  77429. final class TestSuiteSorter
  77430. {
  77431. /**
  77432. * @var int
  77433. */
  77434. public const ORDER_DEFAULT = 0;
  77435. /**
  77436. * @var int
  77437. */
  77438. public const ORDER_RANDOMIZED = 1;
  77439. /**
  77440. * @var int
  77441. */
  77442. public const ORDER_REVERSED = 2;
  77443. /**
  77444. * @var int
  77445. */
  77446. public const ORDER_DEFECTS_FIRST = 3;
  77447. /**
  77448. * @var int
  77449. */
  77450. public const ORDER_DURATION = 4;
  77451. /**
  77452. * @var int
  77453. */
  77454. public const ORDER_SIZE = 5;
  77455. private const SIZE_SORT_WEIGHT = ['small' => 1, 'medium' => 2, 'large' => 3, 'unknown' => 4];
  77456. /**
  77457. * @psalm-var array<string, int> Associative array of (string => DEFECT_SORT_WEIGHT) elements
  77458. */
  77459. private array $defectSortOrder = [];
  77460. private readonly ResultCache $cache;
  77461. /**
  77462. * @psalm-var array<string> A list of normalized names of tests before reordering
  77463. */
  77464. private array $originalExecutionOrder = [];
  77465. /**
  77466. * @psalm-var array<string> A list of normalized names of tests affected by reordering
  77467. */
  77468. private array $executionOrder = [];
  77469. public function __construct(?ResultCache $cache = null)
  77470. {
  77471. $this->cache = $cache ?? new NullResultCache();
  77472. }
  77473. /**
  77474. * @throws Exception
  77475. */
  77476. public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDependencies, int $orderDefects, bool $isRootTestSuite = \true): void
  77477. {
  77478. $allowedOrders = [self::ORDER_DEFAULT, self::ORDER_REVERSED, self::ORDER_RANDOMIZED, self::ORDER_DURATION, self::ORDER_SIZE];
  77479. if (!in_array($order, $allowedOrders, \true)) {
  77480. throw new \PHPUnit\Runner\InvalidOrderException();
  77481. }
  77482. $allowedOrderDefects = [self::ORDER_DEFAULT, self::ORDER_DEFECTS_FIRST];
  77483. if (!in_array($orderDefects, $allowedOrderDefects, \true)) {
  77484. throw new \PHPUnit\Runner\InvalidOrderException();
  77485. }
  77486. if ($isRootTestSuite) {
  77487. $this->originalExecutionOrder = $this->calculateTestExecutionOrder($suite);
  77488. }
  77489. if ($suite instanceof TestSuite) {
  77490. foreach ($suite as $_suite) {
  77491. $this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects, \false);
  77492. }
  77493. if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
  77494. $this->addSuiteToDefectSortOrder($suite);
  77495. }
  77496. $this->sort($suite, $order, $resolveDependencies, $orderDefects);
  77497. }
  77498. if ($isRootTestSuite) {
  77499. $this->executionOrder = $this->calculateTestExecutionOrder($suite);
  77500. }
  77501. }
  77502. public function getOriginalExecutionOrder(): array
  77503. {
  77504. return $this->originalExecutionOrder;
  77505. }
  77506. public function getExecutionOrder(): array
  77507. {
  77508. return $this->executionOrder;
  77509. }
  77510. private function sort(TestSuite $suite, int $order, bool $resolveDependencies, int $orderDefects): void
  77511. {
  77512. if (empty($suite->tests())) {
  77513. return;
  77514. }
  77515. if ($order === self::ORDER_REVERSED) {
  77516. $suite->setTests($this->reverse($suite->tests()));
  77517. } elseif ($order === self::ORDER_RANDOMIZED) {
  77518. $suite->setTests($this->randomize($suite->tests()));
  77519. } elseif ($order === self::ORDER_DURATION) {
  77520. $suite->setTests($this->sortByDuration($suite->tests()));
  77521. } elseif ($order === self::ORDER_SIZE) {
  77522. $suite->setTests($this->sortBySize($suite->tests()));
  77523. }
  77524. if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
  77525. $suite->setTests($this->sortDefectsFirst($suite->tests()));
  77526. }
  77527. if ($resolveDependencies && !$suite instanceof DataProviderTestSuite) {
  77528. $tests = $suite->tests();
  77529. $suite->setTests($this->resolveDependencies($tests));
  77530. }
  77531. }
  77532. private function addSuiteToDefectSortOrder(TestSuite $suite): void
  77533. {
  77534. $max = 0;
  77535. foreach ($suite->tests() as $test) {
  77536. if (!$test instanceof Reorderable) {
  77537. continue;
  77538. }
  77539. if (!isset($this->defectSortOrder[$test->sortId()])) {
  77540. $this->defectSortOrder[$test->sortId()] = $this->cache->status($test->sortId())->asInt();
  77541. $max = max($max, $this->defectSortOrder[$test->sortId()]);
  77542. }
  77543. }
  77544. $this->defectSortOrder[$suite->sortId()] = $max;
  77545. }
  77546. private function reverse(array $tests): array
  77547. {
  77548. return array_reverse($tests);
  77549. }
  77550. private function randomize(array $tests): array
  77551. {
  77552. shuffle($tests);
  77553. return $tests;
  77554. }
  77555. private function sortDefectsFirst(array $tests): array
  77556. {
  77557. usort($tests, fn($left, $right) => $this->cmpDefectPriorityAndTime($left, $right));
  77558. return $tests;
  77559. }
  77560. private function sortByDuration(array $tests): array
  77561. {
  77562. usort($tests, fn($left, $right) => $this->cmpDuration($left, $right));
  77563. return $tests;
  77564. }
  77565. private function sortBySize(array $tests): array
  77566. {
  77567. usort($tests, fn($left, $right) => $this->cmpSize($left, $right));
  77568. return $tests;
  77569. }
  77570. /**
  77571. * Comparator callback function to sort tests for "reach failure as fast as possible".
  77572. *
  77573. * 1. sort tests by defect weight defined in self::DEFECT_SORT_WEIGHT
  77574. * 2. when tests are equally defective, sort the fastest to the front
  77575. * 3. do not reorder successful tests
  77576. */
  77577. private function cmpDefectPriorityAndTime(Test $a, Test $b): int
  77578. {
  77579. if (!($a instanceof Reorderable && $b instanceof Reorderable)) {
  77580. return 0;
  77581. }
  77582. $priorityA = $this->defectSortOrder[$a->sortId()] ?? 0;
  77583. $priorityB = $this->defectSortOrder[$b->sortId()] ?? 0;
  77584. if ($priorityB <=> $priorityA) {
  77585. // Sort defect weight descending
  77586. return $priorityB <=> $priorityA;
  77587. }
  77588. if ($priorityA || $priorityB) {
  77589. return $this->cmpDuration($a, $b);
  77590. }
  77591. // do not change execution order
  77592. return 0;
  77593. }
  77594. /**
  77595. * Compares test duration for sorting tests by duration ascending.
  77596. */
  77597. private function cmpDuration(Test $a, Test $b): int
  77598. {
  77599. if (!($a instanceof Reorderable && $b instanceof Reorderable)) {
  77600. return 0;
  77601. }
  77602. return $this->cache->time($a->sortId()) <=> $this->cache->time($b->sortId());
  77603. }
  77604. /**
  77605. * Compares test size for sorting tests small->medium->large->unknown.
  77606. */
  77607. private function cmpSize(Test $a, Test $b): int
  77608. {
  77609. $sizeA = $a instanceof TestCase || $a instanceof DataProviderTestSuite ? $a->size()->asString() : 'unknown';
  77610. $sizeB = $b instanceof TestCase || $b instanceof DataProviderTestSuite ? $b->size()->asString() : 'unknown';
  77611. return self::SIZE_SORT_WEIGHT[$sizeA] <=> self::SIZE_SORT_WEIGHT[$sizeB];
  77612. }
  77613. /**
  77614. * Reorder Tests within a TestCase in such a way as to resolve as many dependencies as possible.
  77615. * The algorithm will leave the tests in original running order when it can.
  77616. * For more details see the documentation for test dependencies.
  77617. *
  77618. * Short description of algorithm:
  77619. * 1. Pick the next Test from remaining tests to be checked for dependencies.
  77620. * 2. If the test has no dependencies: mark done, start again from the top
  77621. * 3. If the test has dependencies but none left to do: mark done, start again from the top
  77622. * 4. When we reach the end add any leftover tests to the end. These will be marked 'skipped' during execution.
  77623. *
  77624. * @psalm-param array<DataProviderTestSuite|TestCase> $tests
  77625. *
  77626. * @psalm-return array<DataProviderTestSuite|TestCase>
  77627. */
  77628. private function resolveDependencies(array $tests): array
  77629. {
  77630. $newTestOrder = [];
  77631. $i = 0;
  77632. $provided = [];
  77633. do {
  77634. if ([] === array_diff($tests[$i]->requires(), $provided)) {
  77635. $provided = array_merge($provided, $tests[$i]->provides());
  77636. $newTestOrder = array_merge($newTestOrder, array_splice($tests, $i, 1));
  77637. $i = 0;
  77638. } else {
  77639. $i++;
  77640. }
  77641. } while (!empty($tests) && $i < count($tests));
  77642. return array_merge($newTestOrder, $tests);
  77643. }
  77644. private function calculateTestExecutionOrder(Test $suite): array
  77645. {
  77646. $tests = [];
  77647. if ($suite instanceof TestSuite) {
  77648. foreach ($suite->tests() as $test) {
  77649. if (!$test instanceof TestSuite && $test instanceof Reorderable) {
  77650. $tests[] = $test->sortId();
  77651. } else {
  77652. $tests = array_merge($tests, $this->calculateTestExecutionOrder($test));
  77653. }
  77654. }
  77655. }
  77656. return $tests;
  77657. }
  77658. }
  77659. <?php
  77660. declare (strict_types=1);
  77661. /*
  77662. * This file is part of PHPUnit.
  77663. *
  77664. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  77665. *
  77666. * For the full copyright and license information, please view the LICENSE
  77667. * file that was distributed with this source code.
  77668. */
  77669. namespace PHPUnit\Runner;
  77670. use function array_slice;
  77671. use function dirname;
  77672. use function explode;
  77673. use function implode;
  77674. use function str_contains;
  77675. use PHPUnitPHAR\SebastianBergmann\Version as VersionId;
  77676. /**
  77677. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  77678. */
  77679. final class Version
  77680. {
  77681. private static string $pharVersion = '10.5.40';
  77682. private static string $version = '';
  77683. /**
  77684. * Returns the current version of PHPUnit.
  77685. */
  77686. public static function id(): string
  77687. {
  77688. if (self::$pharVersion !== '') {
  77689. return self::$pharVersion;
  77690. }
  77691. if (self::$version === '') {
  77692. self::$version = (new VersionId('10.5.40', dirname(__DIR__, 2)))->asString();
  77693. }
  77694. return self::$version;
  77695. }
  77696. public static function series(): string
  77697. {
  77698. if (str_contains(self::id(), '-')) {
  77699. $version = explode('-', self::id(), 2)[0];
  77700. } else {
  77701. $version = self::id();
  77702. }
  77703. return implode('.', array_slice(explode('.', $version), 0, 2));
  77704. }
  77705. public static function majorVersionNumber(): int
  77706. {
  77707. return (int) explode('.', self::series())[0];
  77708. }
  77709. public static function getVersionString(): string
  77710. {
  77711. return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.';
  77712. }
  77713. }
  77714. <?php
  77715. declare (strict_types=1);
  77716. /*
  77717. * This file is part of PHPUnit.
  77718. *
  77719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  77720. *
  77721. * For the full copyright and license information, please view the LICENSE
  77722. * file that was distributed with this source code.
  77723. */
  77724. namespace PHPUnit\TextUI;
  77725. use const PHP_EOL;
  77726. use const PHP_VERSION;
  77727. use function is_file;
  77728. use function is_readable;
  77729. use function printf;
  77730. use function realpath;
  77731. use function sprintf;
  77732. use function trim;
  77733. use function unlink;
  77734. use PHPUnit\Event\EventFacadeIsSealedException;
  77735. use PHPUnit\Event\Facade as EventFacade;
  77736. use PHPUnit\Event\UnknownSubscriberTypeException;
  77737. use PHPUnit\Framework\TestSuite;
  77738. use PHPUnit\Logging\EventLogger;
  77739. use PHPUnit\Logging\JUnit\JunitXmlLogger;
  77740. use PHPUnit\Logging\TeamCity\TeamCityLogger;
  77741. use PHPUnit\Logging\TestDox\HtmlRenderer as TestDoxHtmlRenderer;
  77742. use PHPUnit\Logging\TestDox\PlainTextRenderer as TestDoxTextRenderer;
  77743. use PHPUnit\Logging\TestDox\TestResultCollector as TestDoxResultCollector;
  77744. use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi;
  77745. use PHPUnit\Runner\Baseline\CannotLoadBaselineException;
  77746. use PHPUnit\Runner\Baseline\Generator as BaselineGenerator;
  77747. use PHPUnit\Runner\Baseline\Reader;
  77748. use PHPUnit\Runner\Baseline\Writer;
  77749. use PHPUnit\Runner\CodeCoverage;
  77750. use PHPUnit\Runner\DirectoryDoesNotExistException;
  77751. use PHPUnit\Runner\ErrorHandler;
  77752. use PHPUnit\Runner\Extension\ExtensionBootstrapper;
  77753. use PHPUnit\Runner\Extension\Facade as ExtensionFacade;
  77754. use PHPUnit\Runner\Extension\PharLoader;
  77755. use PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler;
  77756. use PHPUnit\Runner\ResultCache\DefaultResultCache;
  77757. use PHPUnit\Runner\ResultCache\NullResultCache;
  77758. use PHPUnit\Runner\ResultCache\ResultCache;
  77759. use PHPUnit\Runner\ResultCache\ResultCacheHandler;
  77760. use PHPUnit\Runner\TestSuiteSorter;
  77761. use PHPUnit\Runner\Version;
  77762. use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
  77763. use PHPUnit\TextUI\CliArguments\Builder;
  77764. use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
  77765. use PHPUnit\TextUI\CliArguments\Exception as ArgumentsException;
  77766. use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
  77767. use PHPUnit\TextUI\Command\AtLeastVersionCommand;
  77768. use PHPUnit\TextUI\Command\GenerateConfigurationCommand;
  77769. use PHPUnit\TextUI\Command\ListGroupsCommand;
  77770. use PHPUnit\TextUI\Command\ListTestsAsTextCommand;
  77771. use PHPUnit\TextUI\Command\ListTestsAsXmlCommand;
  77772. use PHPUnit\TextUI\Command\ListTestSuitesCommand;
  77773. use PHPUnit\TextUI\Command\MigrateConfigurationCommand;
  77774. use PHPUnit\TextUI\Command\Result;
  77775. use PHPUnit\TextUI\Command\ShowHelpCommand;
  77776. use PHPUnit\TextUI\Command\ShowVersionCommand;
  77777. use PHPUnit\TextUI\Command\VersionCheckCommand;
  77778. use PHPUnit\TextUI\Command\WarmCodeCoverageCacheCommand;
  77779. use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
  77780. use PHPUnit\TextUI\Configuration\Configuration;
  77781. use PHPUnit\TextUI\Configuration\PhpHandler;
  77782. use PHPUnit\TextUI\Configuration\Registry;
  77783. use PHPUnit\TextUI\Configuration\TestSuiteBuilder;
  77784. use PHPUnit\TextUI\Output\DefaultPrinter;
  77785. use PHPUnit\TextUI\Output\Facade as OutputFacade;
  77786. use PHPUnit\TextUI\Output\Printer;
  77787. use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
  77788. use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration;
  77789. use PHPUnit\TextUI\XmlConfiguration\Loader;
  77790. use PHPUnit\Util\Http\PhpDownloader;
  77791. use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
  77792. use Throwable;
  77793. /**
  77794. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  77795. *
  77796. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  77797. */
  77798. final class Application
  77799. {
  77800. public function run(array $argv): int
  77801. {
  77802. try {
  77803. EventFacade::emitter()->applicationStarted();
  77804. $cliConfiguration = $this->buildCliConfiguration($argv);
  77805. $pathToXmlConfigurationFile = (new XmlConfigurationFileFinder())->find($cliConfiguration);
  77806. $this->executeCommandsThatOnlyRequireCliConfiguration($cliConfiguration, $pathToXmlConfigurationFile);
  77807. $xmlConfiguration = $this->loadXmlConfiguration($pathToXmlConfigurationFile);
  77808. $configuration = Registry::init($cliConfiguration, $xmlConfiguration);
  77809. (new PhpHandler())->handle($configuration->php());
  77810. if ($configuration->hasBootstrap()) {
  77811. $this->loadBootstrapScript($configuration->bootstrap());
  77812. }
  77813. $this->executeCommandsThatRequireCompleteConfiguration($configuration, $cliConfiguration);
  77814. $testSuite = $this->buildTestSuite($configuration);
  77815. $this->executeCommandsThatRequireCliConfigurationAndTestSuite($cliConfiguration, $testSuite);
  77816. $this->executeHelpCommandWhenThereIsNothingElseToDo($configuration, $testSuite);
  77817. $pharExtensions = null;
  77818. $extensionRequiresCodeCoverageCollection = \false;
  77819. $extensionReplacesOutput = \false;
  77820. $extensionReplacesProgressOutput = \false;
  77821. $extensionReplacesResultOutput = \false;
  77822. $extensionRequiresExportOfObjects = \false;
  77823. if (!$configuration->noExtensions()) {
  77824. if ($configuration->hasPharExtensionDirectory()) {
  77825. $pharExtensions = (new PharLoader())->loadPharExtensionsInDirectory($configuration->pharExtensionDirectory());
  77826. }
  77827. $bootstrappedExtensions = $this->bootstrapExtensions($configuration);
  77828. $extensionRequiresCodeCoverageCollection = $bootstrappedExtensions['requiresCodeCoverageCollection'];
  77829. $extensionReplacesOutput = $bootstrappedExtensions['replacesOutput'];
  77830. $extensionReplacesProgressOutput = $bootstrappedExtensions['replacesProgressOutput'];
  77831. $extensionReplacesResultOutput = $bootstrappedExtensions['replacesResultOutput'];
  77832. $extensionRequiresExportOfObjects = $bootstrappedExtensions['requiresExportOfObjects'];
  77833. }
  77834. if ($extensionRequiresExportOfObjects) {
  77835. EventFacade::emitter()->exportObjects();
  77836. }
  77837. CodeCoverage::instance()->init($configuration, CodeCoverageFilterRegistry::instance(), $extensionRequiresCodeCoverageCollection);
  77838. if (CodeCoverage::instance()->isActive()) {
  77839. CodeCoverage::instance()->ignoreLines((new CodeCoverageMetadataApi())->linesToBeIgnored($testSuite));
  77840. }
  77841. $printer = OutputFacade::init($configuration, $extensionReplacesProgressOutput, $extensionReplacesResultOutput);
  77842. if (!$configuration->debug() && !$extensionReplacesOutput) {
  77843. $this->writeRuntimeInformation($printer, $configuration);
  77844. $this->writePharExtensionInformation($printer, $pharExtensions);
  77845. $this->writeRandomSeedInformation($printer, $configuration);
  77846. $printer->print(PHP_EOL);
  77847. }
  77848. if ($configuration->debug()) {
  77849. EventFacade::instance()->registerTracer(new EventLogger('php://stdout', \false));
  77850. }
  77851. $this->registerLogfileWriters($configuration);
  77852. $testDoxResultCollector = $this->testDoxResultCollector($configuration);
  77853. TestResultFacade::init();
  77854. $resultCache = $this->initializeTestResultCache($configuration);
  77855. if ($configuration->controlGarbageCollector()) {
  77856. new GarbageCollectionHandler(EventFacade::instance(), $configuration->numberOfTestsBeforeGarbageCollection());
  77857. }
  77858. $baselineGenerator = $this->configureBaseline($configuration);
  77859. EventFacade::instance()->seal();
  77860. $timer = new Timer();
  77861. $timer->start();
  77862. $runner = new \PHPUnit\TextUI\TestRunner();
  77863. $runner->run($configuration, $resultCache, $testSuite);
  77864. $duration = $timer->stop();
  77865. $testDoxResult = null;
  77866. if (isset($testDoxResultCollector)) {
  77867. $testDoxResult = $testDoxResultCollector->testMethodsGroupedByClass();
  77868. }
  77869. if ($testDoxResult !== null && $configuration->hasLogfileTestdoxHtml()) {
  77870. try {
  77871. OutputFacade::printerFor($configuration->logfileTestdoxHtml())->print((new TestDoxHtmlRenderer())->render($testDoxResult));
  77872. } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
  77873. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot log test results in TestDox HTML format to "%s": %s', $configuration->logfileTestdoxHtml(), $e->getMessage()));
  77874. }
  77875. }
  77876. if ($testDoxResult !== null && $configuration->hasLogfileTestdoxText()) {
  77877. try {
  77878. OutputFacade::printerFor($configuration->logfileTestdoxText())->print((new TestDoxTextRenderer())->render($testDoxResult));
  77879. } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
  77880. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot log test results in TestDox plain text format to "%s": %s', $configuration->logfileTestdoxText(), $e->getMessage()));
  77881. }
  77882. }
  77883. $result = TestResultFacade::result();
  77884. if (!$extensionReplacesResultOutput && !$configuration->debug()) {
  77885. OutputFacade::printResult($result, $testDoxResult, $duration);
  77886. }
  77887. CodeCoverage::instance()->generateReports($printer, $configuration);
  77888. if (isset($baselineGenerator)) {
  77889. (new Writer())->write($configuration->generateBaseline(), $baselineGenerator->baseline());
  77890. $printer->print(sprintf(PHP_EOL . 'Baseline written to %s.' . PHP_EOL, realpath($configuration->generateBaseline())));
  77891. }
  77892. $shellExitCode = (new \PHPUnit\TextUI\ShellExitCodeCalculator())->calculate($configuration->failOnDeprecation(), $configuration->failOnPhpunitDeprecation(), $configuration->failOnEmptyTestSuite(), $configuration->failOnIncomplete(), $configuration->failOnNotice(), $configuration->failOnRisky(), $configuration->failOnSkipped(), $configuration->failOnWarning(), $result);
  77893. EventFacade::emitter()->applicationFinished($shellExitCode);
  77894. return $shellExitCode;
  77895. // @codeCoverageIgnoreStart
  77896. } catch (Throwable $t) {
  77897. $this->exitWithCrashMessage($t);
  77898. }
  77899. // @codeCoverageIgnoreEnd
  77900. }
  77901. private function execute(\PHPUnit\TextUI\Command\Command $command, bool $requiresResultCollectedFromEvents = \false): never
  77902. {
  77903. if ($requiresResultCollectedFromEvents) {
  77904. try {
  77905. TestResultFacade::init();
  77906. EventFacade::instance()->seal();
  77907. $resultCollectedFromEvents = TestResultFacade::result();
  77908. } catch (EventFacadeIsSealedException|UnknownSubscriberTypeException) {
  77909. }
  77910. }
  77911. print Version::getVersionString() . PHP_EOL . PHP_EOL;
  77912. $result = $command->execute();
  77913. print $result->output();
  77914. $shellExitCode = $result->shellExitCode();
  77915. if (isset($resultCollectedFromEvents) && $resultCollectedFromEvents->hasTestTriggeredPhpunitErrorEvents()) {
  77916. $shellExitCode = Result::EXCEPTION;
  77917. print PHP_EOL . PHP_EOL . 'There were errors:' . PHP_EOL;
  77918. foreach ($resultCollectedFromEvents->testTriggeredPhpunitErrorEvents() as $events) {
  77919. foreach ($events as $event) {
  77920. print PHP_EOL . trim($event->message()) . PHP_EOL;
  77921. }
  77922. }
  77923. }
  77924. exit($shellExitCode);
  77925. }
  77926. private function loadBootstrapScript(string $filename): void
  77927. {
  77928. if (!is_readable($filename)) {
  77929. $this->exitWithErrorMessage(sprintf('Cannot open bootstrap script "%s"', $filename));
  77930. }
  77931. try {
  77932. include_once $filename;
  77933. } catch (Throwable $t) {
  77934. $message = sprintf('Error in bootstrap script: %s:%s%s%s%s', $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString());
  77935. while ($t = $t->getPrevious()) {
  77936. $message .= sprintf('%s%sPrevious error: %s:%s%s%s%s', PHP_EOL, PHP_EOL, $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString());
  77937. }
  77938. $this->exitWithErrorMessage($message);
  77939. }
  77940. EventFacade::emitter()->testRunnerBootstrapFinished($filename);
  77941. }
  77942. private function buildCliConfiguration(array $argv): CliConfiguration
  77943. {
  77944. try {
  77945. $cliConfiguration = (new Builder())->fromParameters($argv);
  77946. } catch (ArgumentsException $e) {
  77947. $this->exitWithErrorMessage($e->getMessage());
  77948. }
  77949. return $cliConfiguration;
  77950. }
  77951. private function loadXmlConfiguration(false|string $configurationFile): XmlConfiguration
  77952. {
  77953. if ($configurationFile === \false) {
  77954. return DefaultConfiguration::create();
  77955. }
  77956. try {
  77957. return (new Loader())->load($configurationFile);
  77958. } catch (Throwable $e) {
  77959. $this->exitWithErrorMessage($e->getMessage());
  77960. }
  77961. }
  77962. private function buildTestSuite(Configuration $configuration): TestSuite
  77963. {
  77964. try {
  77965. return (new TestSuiteBuilder())->build($configuration);
  77966. } catch (\PHPUnit\TextUI\Exception $e) {
  77967. $this->exitWithErrorMessage($e->getMessage());
  77968. }
  77969. }
  77970. /**
  77971. * @psalm-return array{requiresCodeCoverageCollection: bool, replacesOutput: bool, replacesProgressOutput: bool, replacesResultOutput: bool, requiresExportOfObjects: bool}
  77972. */
  77973. private function bootstrapExtensions(Configuration $configuration): array
  77974. {
  77975. $facade = new ExtensionFacade();
  77976. $extensionBootstrapper = new ExtensionBootstrapper($configuration, $facade);
  77977. foreach ($configuration->extensionBootstrappers() as $bootstrapper) {
  77978. $extensionBootstrapper->bootstrap($bootstrapper['className'], $bootstrapper['parameters']);
  77979. }
  77980. return ['requiresCodeCoverageCollection' => $facade->requiresCodeCoverageCollection(), 'replacesOutput' => $facade->replacesOutput(), 'replacesProgressOutput' => $facade->replacesProgressOutput(), 'replacesResultOutput' => $facade->replacesResultOutput(), 'requiresExportOfObjects' => $facade->requiresExportOfObjects()];
  77981. }
  77982. private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration $cliConfiguration, false|string $configurationFile): void
  77983. {
  77984. if ($cliConfiguration->generateConfiguration()) {
  77985. $this->execute(new GenerateConfigurationCommand());
  77986. }
  77987. if ($cliConfiguration->migrateConfiguration()) {
  77988. if ($configurationFile === \false) {
  77989. $this->exitWithErrorMessage('No configuration file found to migrate');
  77990. }
  77991. $this->execute(new MigrateConfigurationCommand(realpath($configurationFile)));
  77992. }
  77993. if ($cliConfiguration->hasAtLeastVersion()) {
  77994. $this->execute(new AtLeastVersionCommand($cliConfiguration->atLeastVersion()));
  77995. }
  77996. if ($cliConfiguration->version()) {
  77997. $this->execute(new ShowVersionCommand());
  77998. }
  77999. if ($cliConfiguration->checkVersion()) {
  78000. $this->execute(new VersionCheckCommand(new PhpDownloader(), Version::majorVersionNumber(), Version::id()));
  78001. }
  78002. if ($cliConfiguration->help()) {
  78003. $this->execute(new ShowHelpCommand(Result::SUCCESS));
  78004. }
  78005. }
  78006. private function executeCommandsThatRequireCliConfigurationAndTestSuite(CliConfiguration $cliConfiguration, TestSuite $testSuite): void
  78007. {
  78008. if ($cliConfiguration->listGroups()) {
  78009. $this->execute(new ListGroupsCommand($testSuite), \true);
  78010. }
  78011. if ($cliConfiguration->listTests()) {
  78012. $this->execute(new ListTestsAsTextCommand($testSuite), \true);
  78013. }
  78014. if ($cliConfiguration->hasListTestsXml()) {
  78015. $this->execute(new ListTestsAsXmlCommand($cliConfiguration->listTestsXml(), $testSuite), \true);
  78016. }
  78017. }
  78018. private function executeCommandsThatRequireCompleteConfiguration(Configuration $configuration, CliConfiguration $cliConfiguration): void
  78019. {
  78020. if ($cliConfiguration->listSuites()) {
  78021. $this->execute(new ListTestSuitesCommand($configuration->testSuite()));
  78022. }
  78023. if ($cliConfiguration->warmCoverageCache()) {
  78024. $this->execute(new WarmCodeCoverageCacheCommand($configuration, CodeCoverageFilterRegistry::instance()));
  78025. }
  78026. }
  78027. private function executeHelpCommandWhenThereIsNothingElseToDo(Configuration $configuration, TestSuite $testSuite): void
  78028. {
  78029. if ($testSuite->isEmpty() && !$configuration->hasCliArguments() && $configuration->testSuite()->isEmpty()) {
  78030. $this->execute(new ShowHelpCommand(Result::FAILURE));
  78031. }
  78032. }
  78033. private function writeRuntimeInformation(Printer $printer, Configuration $configuration): void
  78034. {
  78035. $printer->print(Version::getVersionString() . PHP_EOL . PHP_EOL);
  78036. $runtime = 'PHP ' . PHP_VERSION;
  78037. if (CodeCoverage::instance()->isActive()) {
  78038. $runtime .= ' with ' . CodeCoverage::instance()->driver()->nameAndVersion();
  78039. }
  78040. $this->writeMessage($printer, 'Runtime', $runtime);
  78041. if ($configuration->hasConfigurationFile()) {
  78042. $this->writeMessage($printer, 'Configuration', $configuration->configurationFile());
  78043. }
  78044. }
  78045. /**
  78046. * @psalm-param ?list<string> $pharExtensions
  78047. */
  78048. private function writePharExtensionInformation(Printer $printer, ?array $pharExtensions): void
  78049. {
  78050. if ($pharExtensions === null) {
  78051. return;
  78052. }
  78053. foreach ($pharExtensions as $extension) {
  78054. $this->writeMessage($printer, 'Extension', $extension);
  78055. }
  78056. }
  78057. private function writeMessage(Printer $printer, string $type, string $message): void
  78058. {
  78059. $printer->print(sprintf("%-15s%s\n", $type . ':', $message));
  78060. }
  78061. private function writeRandomSeedInformation(Printer $printer, Configuration $configuration): void
  78062. {
  78063. if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) {
  78064. $this->writeMessage($printer, 'Random Seed', (string) $configuration->randomOrderSeed());
  78065. }
  78066. }
  78067. /**
  78068. * @throws EventFacadeIsSealedException
  78069. * @throws UnknownSubscriberTypeException
  78070. */
  78071. private function registerLogfileWriters(Configuration $configuration): void
  78072. {
  78073. if ($configuration->hasLogEventsText()) {
  78074. if (is_file($configuration->logEventsText())) {
  78075. unlink($configuration->logEventsText());
  78076. }
  78077. EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsText(), \false));
  78078. }
  78079. if ($configuration->hasLogEventsVerboseText()) {
  78080. if (is_file($configuration->logEventsVerboseText())) {
  78081. unlink($configuration->logEventsVerboseText());
  78082. }
  78083. EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsVerboseText(), \true));
  78084. EventFacade::emitter()->exportObjects();
  78085. }
  78086. if ($configuration->hasLogfileJunit()) {
  78087. try {
  78088. new JunitXmlLogger(OutputFacade::printerFor($configuration->logfileJunit()), EventFacade::instance());
  78089. } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
  78090. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot log test results in JUnit XML format to "%s": %s', $configuration->logfileJunit(), $e->getMessage()));
  78091. }
  78092. }
  78093. if ($configuration->hasLogfileTeamcity()) {
  78094. try {
  78095. new TeamCityLogger(DefaultPrinter::from($configuration->logfileTeamcity()), EventFacade::instance());
  78096. } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
  78097. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot log test results in TeamCity format to "%s": %s', $configuration->logfileTeamcity(), $e->getMessage()));
  78098. }
  78099. }
  78100. }
  78101. /**
  78102. * @throws EventFacadeIsSealedException
  78103. * @throws UnknownSubscriberTypeException
  78104. */
  78105. private function testDoxResultCollector(Configuration $configuration): ?TestDoxResultCollector
  78106. {
  78107. if ($configuration->hasLogfileTestdoxHtml() || $configuration->hasLogfileTestdoxText() || $configuration->outputIsTestDox()) {
  78108. return new TestDoxResultCollector(EventFacade::instance(), $configuration->source());
  78109. }
  78110. return null;
  78111. }
  78112. /**
  78113. * @throws EventFacadeIsSealedException
  78114. * @throws UnknownSubscriberTypeException
  78115. */
  78116. private function initializeTestResultCache(Configuration $configuration): ResultCache
  78117. {
  78118. if ($configuration->cacheResult()) {
  78119. $cache = new DefaultResultCache($configuration->testResultCacheFile());
  78120. new ResultCacheHandler($cache, EventFacade::instance());
  78121. return $cache;
  78122. }
  78123. return new NullResultCache();
  78124. }
  78125. /**
  78126. * @throws EventFacadeIsSealedException
  78127. * @throws UnknownSubscriberTypeException
  78128. */
  78129. private function configureBaseline(Configuration $configuration): ?BaselineGenerator
  78130. {
  78131. if ($configuration->hasGenerateBaseline()) {
  78132. return new BaselineGenerator(EventFacade::instance(), $configuration->source());
  78133. }
  78134. if ($configuration->source()->useBaseline()) {
  78135. /** @psalm-suppress MissingThrowsDocblock */
  78136. $baselineFile = $configuration->source()->baseline();
  78137. $baseline = null;
  78138. try {
  78139. $baseline = (new Reader())->read($baselineFile);
  78140. } catch (CannotLoadBaselineException $e) {
  78141. EventFacade::emitter()->testRunnerTriggeredWarning($e->getMessage());
  78142. }
  78143. if ($baseline !== null) {
  78144. ErrorHandler::instance()->use($baseline);
  78145. }
  78146. }
  78147. return null;
  78148. }
  78149. /**
  78150. * @codeCoverageIgnore
  78151. */
  78152. private function exitWithCrashMessage(Throwable $t): never
  78153. {
  78154. $message = $t->getMessage();
  78155. if (empty(trim($message))) {
  78156. $message = '(no message)';
  78157. }
  78158. printf('%s%sAn error occurred inside PHPUnit.%s%sMessage: %s', PHP_EOL, PHP_EOL, PHP_EOL, PHP_EOL, $message);
  78159. $first = \true;
  78160. if ($t->getPrevious()) {
  78161. $t = $t->getPrevious();
  78162. }
  78163. do {
  78164. printf('%s%s: %s:%d%s%s%s%s', PHP_EOL, $first ? 'Location' : 'Caused by', $t->getFile(), $t->getLine(), PHP_EOL, PHP_EOL, $t->getTraceAsString(), PHP_EOL);
  78165. $first = \false;
  78166. } while ($t = $t->getPrevious());
  78167. exit(Result::CRASH);
  78168. }
  78169. private function exitWithErrorMessage(string $message): never
  78170. {
  78171. print Version::getVersionString() . PHP_EOL . PHP_EOL . $message . PHP_EOL;
  78172. exit(Result::EXCEPTION);
  78173. }
  78174. }
  78175. <?php
  78176. declare (strict_types=1);
  78177. /*
  78178. * This file is part of PHPUnit.
  78179. *
  78180. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78181. *
  78182. * For the full copyright and license information, please view the LICENSE
  78183. * file that was distributed with this source code.
  78184. */
  78185. namespace PHPUnit\TextUI\Command;
  78186. /**
  78187. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78188. *
  78189. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78190. */
  78191. interface Command
  78192. {
  78193. public function execute(): \PHPUnit\TextUI\Command\Result;
  78194. }
  78195. <?php
  78196. declare (strict_types=1);
  78197. /*
  78198. * This file is part of PHPUnit.
  78199. *
  78200. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78201. *
  78202. * For the full copyright and license information, please view the LICENSE
  78203. * file that was distributed with this source code.
  78204. */
  78205. namespace PHPUnit\TextUI\Command;
  78206. use function version_compare;
  78207. use PHPUnit\Runner\Version;
  78208. /**
  78209. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78210. *
  78211. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78212. */
  78213. final class AtLeastVersionCommand implements \PHPUnit\TextUI\Command\Command
  78214. {
  78215. private readonly string $version;
  78216. public function __construct(string $version)
  78217. {
  78218. $this->version = $version;
  78219. }
  78220. public function execute(): \PHPUnit\TextUI\Command\Result
  78221. {
  78222. if (version_compare(Version::id(), $this->version, '>=')) {
  78223. return \PHPUnit\TextUI\Command\Result::from();
  78224. }
  78225. return \PHPUnit\TextUI\Command\Result::from('', \PHPUnit\TextUI\Command\Result::FAILURE);
  78226. }
  78227. }
  78228. <?php
  78229. declare (strict_types=1);
  78230. /*
  78231. * This file is part of PHPUnit.
  78232. *
  78233. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78234. *
  78235. * For the full copyright and license information, please view the LICENSE
  78236. * file that was distributed with this source code.
  78237. */
  78238. namespace PHPUnit\TextUI\Command;
  78239. use const PHP_EOL;
  78240. use const STDIN;
  78241. use function fgets;
  78242. use function file_put_contents;
  78243. use function getcwd;
  78244. use function sprintf;
  78245. use function trim;
  78246. use PHPUnit\Runner\Version;
  78247. use PHPUnit\TextUI\XmlConfiguration\Generator;
  78248. /**
  78249. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78250. *
  78251. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78252. */
  78253. final class GenerateConfigurationCommand implements \PHPUnit\TextUI\Command\Command
  78254. {
  78255. public function execute(): \PHPUnit\TextUI\Command\Result
  78256. {
  78257. print 'Generating phpunit.xml in ' . getcwd() . PHP_EOL . PHP_EOL;
  78258. print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): ';
  78259. $bootstrapScript = $this->read();
  78260. print 'Tests directory (relative to path shown above; default: tests): ';
  78261. $testsDirectory = $this->read();
  78262. print 'Source directory (relative to path shown above; default: src): ';
  78263. $src = $this->read();
  78264. print 'Cache directory (relative to path shown above; default: .phpunit.cache): ';
  78265. $cacheDirectory = $this->read();
  78266. if ($bootstrapScript === '') {
  78267. $bootstrapScript = 'vendor/autoload.php';
  78268. }
  78269. if ($testsDirectory === '') {
  78270. $testsDirectory = 'tests';
  78271. }
  78272. if ($src === '') {
  78273. $src = 'src';
  78274. }
  78275. if ($cacheDirectory === '') {
  78276. $cacheDirectory = '.phpunit.cache';
  78277. }
  78278. $generator = new Generator();
  78279. $result = @file_put_contents('phpunit.xml', $generator->generateDefaultConfiguration(Version::series(), $bootstrapScript, $testsDirectory, $src, $cacheDirectory));
  78280. if ($result !== \false) {
  78281. return \PHPUnit\TextUI\Command\Result::from(sprintf(PHP_EOL . 'Generated phpunit.xml in %s.' . PHP_EOL . 'Make sure to exclude the %s directory from version control.' . PHP_EOL, getcwd(), $cacheDirectory));
  78282. }
  78283. // @codeCoverageIgnoreStart
  78284. return \PHPUnit\TextUI\Command\Result::from(sprintf(PHP_EOL . 'Could not write phpunit.xml in %s.' . PHP_EOL, getcwd()), \PHPUnit\TextUI\Command\Result::EXCEPTION);
  78285. // @codeCoverageIgnoreEnd
  78286. }
  78287. private function read(): string
  78288. {
  78289. return trim(fgets(STDIN));
  78290. }
  78291. }
  78292. <?php
  78293. declare (strict_types=1);
  78294. /*
  78295. * This file is part of PHPUnit.
  78296. *
  78297. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78298. *
  78299. * For the full copyright and license information, please view the LICENSE
  78300. * file that was distributed with this source code.
  78301. */
  78302. namespace PHPUnit\TextUI\Command;
  78303. use const PHP_EOL;
  78304. use function sort;
  78305. use function sprintf;
  78306. use function str_starts_with;
  78307. use PHPUnit\Framework\TestSuite;
  78308. use PHPUnit\TextUI\Configuration\Registry;
  78309. /**
  78310. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78311. *
  78312. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78313. */
  78314. final class ListGroupsCommand implements \PHPUnit\TextUI\Command\Command
  78315. {
  78316. private readonly TestSuite $suite;
  78317. public function __construct(TestSuite $suite)
  78318. {
  78319. $this->suite = $suite;
  78320. }
  78321. public function execute(): \PHPUnit\TextUI\Command\Result
  78322. {
  78323. $buffer = $this->warnAboutConflictingOptions();
  78324. $buffer .= 'Available test group(s):' . PHP_EOL;
  78325. $groups = $this->suite->groups();
  78326. sort($groups);
  78327. foreach ($groups as $group) {
  78328. if (str_starts_with($group, '__phpunit_')) {
  78329. continue;
  78330. }
  78331. $buffer .= sprintf(' - %s' . PHP_EOL, $group);
  78332. }
  78333. return \PHPUnit\TextUI\Command\Result::from($buffer);
  78334. }
  78335. private function warnAboutConflictingOptions(): string
  78336. {
  78337. $buffer = '';
  78338. $configuration = Registry::get();
  78339. if ($configuration->hasFilter()) {
  78340. $buffer .= 'The --filter and --list-groups options cannot be combined, --filter is ignored' . PHP_EOL;
  78341. }
  78342. if ($configuration->hasGroups()) {
  78343. $buffer .= 'The --group and --list-groups options cannot be combined, --group is ignored' . PHP_EOL;
  78344. }
  78345. if ($configuration->hasExcludeGroups()) {
  78346. $buffer .= 'The --exclude-group and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78347. }
  78348. if ($configuration->includeTestSuite() !== '') {
  78349. $buffer .= 'The --testsuite and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78350. }
  78351. if (!empty($buffer)) {
  78352. $buffer .= PHP_EOL;
  78353. }
  78354. return $buffer;
  78355. }
  78356. }
  78357. <?php
  78358. declare (strict_types=1);
  78359. /*
  78360. * This file is part of PHPUnit.
  78361. *
  78362. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78363. *
  78364. * For the full copyright and license information, please view the LICENSE
  78365. * file that was distributed with this source code.
  78366. */
  78367. namespace PHPUnit\TextUI\Command;
  78368. use const PHP_EOL;
  78369. use function sprintf;
  78370. use PHPUnit\TextUI\Configuration\Registry;
  78371. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  78372. /**
  78373. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78374. *
  78375. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78376. */
  78377. final class ListTestSuitesCommand implements \PHPUnit\TextUI\Command\Command
  78378. {
  78379. private readonly TestSuiteCollection $suites;
  78380. public function __construct(TestSuiteCollection $suites)
  78381. {
  78382. $this->suites = $suites;
  78383. }
  78384. public function execute(): \PHPUnit\TextUI\Command\Result
  78385. {
  78386. $buffer = $this->warnAboutConflictingOptions();
  78387. $buffer .= 'Available test suite(s):' . PHP_EOL;
  78388. foreach ($this->suites as $suite) {
  78389. $buffer .= sprintf(' - %s' . PHP_EOL, $suite->name());
  78390. }
  78391. return \PHPUnit\TextUI\Command\Result::from($buffer);
  78392. }
  78393. private function warnAboutConflictingOptions(): string
  78394. {
  78395. $buffer = '';
  78396. $configuration = Registry::get();
  78397. if ($configuration->hasFilter()) {
  78398. $buffer .= 'The --filter and --list-suites options cannot be combined, --filter is ignored' . PHP_EOL;
  78399. }
  78400. if ($configuration->hasGroups()) {
  78401. $buffer .= 'The --group and --list-suites options cannot be combined, --group is ignored' . PHP_EOL;
  78402. }
  78403. if ($configuration->hasExcludeGroups()) {
  78404. $buffer .= 'The --exclude-group and --list-suites options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78405. }
  78406. if ($configuration->includeTestSuite() !== '') {
  78407. $buffer .= 'The --testsuite and --list-suites options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78408. }
  78409. if (!empty($buffer)) {
  78410. $buffer .= PHP_EOL;
  78411. }
  78412. return $buffer;
  78413. }
  78414. }
  78415. <?php
  78416. declare (strict_types=1);
  78417. /*
  78418. * This file is part of PHPUnit.
  78419. *
  78420. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78421. *
  78422. * For the full copyright and license information, please view the LICENSE
  78423. * file that was distributed with this source code.
  78424. */
  78425. namespace PHPUnit\TextUI\Command;
  78426. use const PHP_EOL;
  78427. use function sprintf;
  78428. use function str_replace;
  78429. use PHPUnit\Framework\TestCase;
  78430. use PHPUnit\Framework\TestSuite;
  78431. use PHPUnit\Runner\PhptTestCase;
  78432. use PHPUnit\TextUI\Configuration\Registry;
  78433. use RecursiveIteratorIterator;
  78434. /**
  78435. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78436. *
  78437. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78438. */
  78439. final class ListTestsAsTextCommand implements \PHPUnit\TextUI\Command\Command
  78440. {
  78441. private readonly TestSuite $suite;
  78442. public function __construct(TestSuite $suite)
  78443. {
  78444. $this->suite = $suite;
  78445. }
  78446. public function execute(): \PHPUnit\TextUI\Command\Result
  78447. {
  78448. $buffer = $this->warnAboutConflictingOptions();
  78449. $buffer .= 'Available test(s):' . PHP_EOL;
  78450. foreach (new RecursiveIteratorIterator($this->suite) as $test) {
  78451. if ($test instanceof TestCase) {
  78452. $name = sprintf('%s::%s', $test::class, str_replace(' with data set ', '', $test->nameWithDataSet()));
  78453. } elseif ($test instanceof PhptTestCase) {
  78454. $name = $test->getName();
  78455. } else {
  78456. continue;
  78457. }
  78458. $buffer .= sprintf(' - %s' . PHP_EOL, $name);
  78459. }
  78460. return \PHPUnit\TextUI\Command\Result::from($buffer);
  78461. }
  78462. private function warnAboutConflictingOptions(): string
  78463. {
  78464. $buffer = '';
  78465. $configuration = Registry::get();
  78466. if ($configuration->hasFilter()) {
  78467. $buffer .= 'The --filter and --list-tests options cannot be combined, --filter is ignored' . PHP_EOL;
  78468. }
  78469. if ($configuration->hasGroups()) {
  78470. $buffer .= 'The --group and --list-tests options cannot be combined, --group is ignored' . PHP_EOL;
  78471. }
  78472. if ($configuration->hasExcludeGroups()) {
  78473. $buffer .= 'The --exclude-group and --list-tests options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78474. }
  78475. if (!empty($buffer)) {
  78476. $buffer .= PHP_EOL;
  78477. }
  78478. return $buffer;
  78479. }
  78480. }
  78481. <?php
  78482. declare (strict_types=1);
  78483. /*
  78484. * This file is part of PHPUnit.
  78485. *
  78486. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78487. *
  78488. * For the full copyright and license information, please view the LICENSE
  78489. * file that was distributed with this source code.
  78490. */
  78491. namespace PHPUnit\TextUI\Command;
  78492. use const PHP_EOL;
  78493. use function file_put_contents;
  78494. use function implode;
  78495. use function sprintf;
  78496. use function str_replace;
  78497. use PHPUnit\Framework\TestCase;
  78498. use PHPUnit\Framework\TestSuite;
  78499. use PHPUnit\Runner\PhptTestCase;
  78500. use PHPUnit\TextUI\Configuration\Registry;
  78501. use RecursiveIteratorIterator;
  78502. use XMLWriter;
  78503. /**
  78504. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78505. *
  78506. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78507. */
  78508. final class ListTestsAsXmlCommand implements \PHPUnit\TextUI\Command\Command
  78509. {
  78510. private readonly string $filename;
  78511. private readonly TestSuite $suite;
  78512. public function __construct(string $filename, TestSuite $suite)
  78513. {
  78514. $this->filename = $filename;
  78515. $this->suite = $suite;
  78516. }
  78517. public function execute(): \PHPUnit\TextUI\Command\Result
  78518. {
  78519. $buffer = $this->warnAboutConflictingOptions();
  78520. $writer = new XMLWriter();
  78521. $writer->openMemory();
  78522. $writer->setIndent(\true);
  78523. $writer->startDocument();
  78524. $writer->startElement('tests');
  78525. $currentTestCase = null;
  78526. foreach (new RecursiveIteratorIterator($this->suite) as $test) {
  78527. if ($test instanceof TestCase) {
  78528. if ($test::class !== $currentTestCase) {
  78529. if ($currentTestCase !== null) {
  78530. $writer->endElement();
  78531. }
  78532. $writer->startElement('testCaseClass');
  78533. $writer->writeAttribute('name', $test::class);
  78534. $currentTestCase = $test::class;
  78535. }
  78536. $writer->startElement('testCaseMethod');
  78537. $writer->writeAttribute('id', $test->valueObjectForEvents()->id());
  78538. $writer->writeAttribute('name', $test->name());
  78539. $writer->writeAttribute('groups', implode(',', $test->groups()));
  78540. /**
  78541. * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5481
  78542. */
  78543. if (!empty($test->dataSetAsString())) {
  78544. $writer->writeAttribute('dataSet', str_replace(' with data set ', '', $test->dataSetAsString()));
  78545. }
  78546. $writer->endElement();
  78547. continue;
  78548. }
  78549. if ($test instanceof PhptTestCase) {
  78550. if ($currentTestCase !== null) {
  78551. $writer->endElement();
  78552. $currentTestCase = null;
  78553. }
  78554. $writer->startElement('phptFile');
  78555. $writer->writeAttribute('path', $test->getName());
  78556. $writer->endElement();
  78557. }
  78558. }
  78559. if ($currentTestCase !== null) {
  78560. $writer->endElement();
  78561. }
  78562. $writer->endElement();
  78563. file_put_contents($this->filename, $writer->outputMemory());
  78564. $buffer .= sprintf('Wrote list of tests that would have been run to %s' . PHP_EOL, $this->filename);
  78565. return \PHPUnit\TextUI\Command\Result::from($buffer);
  78566. }
  78567. private function warnAboutConflictingOptions(): string
  78568. {
  78569. $buffer = '';
  78570. $configuration = Registry::get();
  78571. if ($configuration->hasFilter()) {
  78572. $buffer .= 'The --filter and --list-tests-xml options cannot be combined, --filter is ignored' . PHP_EOL;
  78573. }
  78574. if ($configuration->hasGroups()) {
  78575. $buffer .= 'The --group and --list-tests-xml options cannot be combined, --group is ignored' . PHP_EOL;
  78576. }
  78577. if ($configuration->hasExcludeGroups()) {
  78578. $buffer .= 'The --exclude-group and --list-tests-xml options cannot be combined, --exclude-group is ignored' . PHP_EOL;
  78579. }
  78580. if (!empty($buffer)) {
  78581. $buffer .= PHP_EOL;
  78582. }
  78583. return $buffer;
  78584. }
  78585. }
  78586. <?php
  78587. declare (strict_types=1);
  78588. /*
  78589. * This file is part of PHPUnit.
  78590. *
  78591. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78592. *
  78593. * For the full copyright and license information, please view the LICENSE
  78594. * file that was distributed with this source code.
  78595. */
  78596. namespace PHPUnit\TextUI\Command;
  78597. use const PHP_EOL;
  78598. use function copy;
  78599. use function file_put_contents;
  78600. use function sprintf;
  78601. use PHPUnit\TextUI\XmlConfiguration\Migrator;
  78602. use Throwable;
  78603. /**
  78604. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78605. *
  78606. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78607. */
  78608. final class MigrateConfigurationCommand implements \PHPUnit\TextUI\Command\Command
  78609. {
  78610. private readonly string $filename;
  78611. public function __construct(string $filename)
  78612. {
  78613. $this->filename = $filename;
  78614. }
  78615. public function execute(): \PHPUnit\TextUI\Command\Result
  78616. {
  78617. try {
  78618. $migrated = (new Migrator())->migrate($this->filename);
  78619. copy($this->filename, $this->filename . '.bak');
  78620. file_put_contents($this->filename, $migrated);
  78621. return \PHPUnit\TextUI\Command\Result::from(sprintf('Created backup: %s.bak%sMigrated configuration: %s%s', $this->filename, PHP_EOL, $this->filename, PHP_EOL));
  78622. } catch (Throwable $t) {
  78623. return \PHPUnit\TextUI\Command\Result::from(sprintf('Migration of %s failed:%s%s%s', $this->filename, PHP_EOL, $t->getMessage(), PHP_EOL), \PHPUnit\TextUI\Command\Result::FAILURE);
  78624. }
  78625. }
  78626. }
  78627. <?php
  78628. declare (strict_types=1);
  78629. /*
  78630. * This file is part of PHPUnit.
  78631. *
  78632. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78633. *
  78634. * For the full copyright and license information, please view the LICENSE
  78635. * file that was distributed with this source code.
  78636. */
  78637. namespace PHPUnit\TextUI\Command;
  78638. use PHPUnit\TextUI\Help;
  78639. /**
  78640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78641. *
  78642. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78643. */
  78644. final class ShowHelpCommand implements \PHPUnit\TextUI\Command\Command
  78645. {
  78646. private readonly int $shellExitCode;
  78647. public function __construct(int $shellExitCode)
  78648. {
  78649. $this->shellExitCode = $shellExitCode;
  78650. }
  78651. public function execute(): \PHPUnit\TextUI\Command\Result
  78652. {
  78653. return \PHPUnit\TextUI\Command\Result::from((new Help())->generate(), $this->shellExitCode);
  78654. }
  78655. }
  78656. <?php
  78657. declare (strict_types=1);
  78658. /*
  78659. * This file is part of PHPUnit.
  78660. *
  78661. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78662. *
  78663. * For the full copyright and license information, please view the LICENSE
  78664. * file that was distributed with this source code.
  78665. */
  78666. namespace PHPUnit\TextUI\Command;
  78667. /**
  78668. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78669. *
  78670. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78671. */
  78672. final class ShowVersionCommand implements \PHPUnit\TextUI\Command\Command
  78673. {
  78674. public function execute(): \PHPUnit\TextUI\Command\Result
  78675. {
  78676. return \PHPUnit\TextUI\Command\Result::from();
  78677. }
  78678. }
  78679. <?php
  78680. declare (strict_types=1);
  78681. /*
  78682. * This file is part of PHPUnit.
  78683. *
  78684. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78685. *
  78686. * For the full copyright and license information, please view the LICENSE
  78687. * file that was distributed with this source code.
  78688. */
  78689. namespace PHPUnit\TextUI\Command;
  78690. use const PHP_EOL;
  78691. use function assert;
  78692. use function sprintf;
  78693. use function version_compare;
  78694. use PHPUnit\Util\Http\Downloader;
  78695. /**
  78696. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78697. *
  78698. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78699. */
  78700. final class VersionCheckCommand implements \PHPUnit\TextUI\Command\Command
  78701. {
  78702. private readonly Downloader $downloader;
  78703. private readonly int $majorVersionNumber;
  78704. private readonly string $versionId;
  78705. public function __construct(Downloader $downloader, int $majorVersionNumber, string $versionId)
  78706. {
  78707. $this->downloader = $downloader;
  78708. $this->majorVersionNumber = $majorVersionNumber;
  78709. $this->versionId = $versionId;
  78710. }
  78711. public function execute(): \PHPUnit\TextUI\Command\Result
  78712. {
  78713. $latestVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit');
  78714. assert($latestVersion !== \false);
  78715. $latestCompatibleVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit-' . $this->majorVersionNumber);
  78716. assert($latestCompatibleVersion !== \false);
  78717. $notLatest = version_compare($latestVersion, $this->versionId, '>');
  78718. $notLatestCompatible = version_compare($latestCompatibleVersion, $this->versionId, '>');
  78719. if (!$notLatest && !$notLatestCompatible) {
  78720. return \PHPUnit\TextUI\Command\Result::from('You are using the latest version of PHPUnit.' . PHP_EOL);
  78721. }
  78722. $buffer = 'You are not using the latest version of PHPUnit.' . PHP_EOL;
  78723. if ($notLatestCompatible) {
  78724. $buffer .= sprintf('The latest version compatible with PHPUnit %s is PHPUnit %s.' . PHP_EOL, $this->versionId, $latestCompatibleVersion);
  78725. }
  78726. if ($notLatest) {
  78727. $buffer .= sprintf('The latest version is PHPUnit %s.' . PHP_EOL, $latestVersion);
  78728. }
  78729. return \PHPUnit\TextUI\Command\Result::from($buffer);
  78730. }
  78731. }
  78732. <?php
  78733. declare (strict_types=1);
  78734. /*
  78735. * This file is part of PHPUnit.
  78736. *
  78737. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78738. *
  78739. * For the full copyright and license information, please view the LICENSE
  78740. * file that was distributed with this source code.
  78741. */
  78742. namespace PHPUnit\TextUI\Command;
  78743. use const PHP_EOL;
  78744. use function printf;
  78745. use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
  78746. use PHPUnit\TextUI\Configuration\Configuration;
  78747. use PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException;
  78748. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\CacheWarmer;
  78749. use PHPUnitPHAR\SebastianBergmann\Timer\NoActiveTimerException;
  78750. use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
  78751. /**
  78752. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78753. *
  78754. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78755. *
  78756. * @codeCoverageIgnore
  78757. */
  78758. final class WarmCodeCoverageCacheCommand implements \PHPUnit\TextUI\Command\Command
  78759. {
  78760. private readonly Configuration $configuration;
  78761. private readonly CodeCoverageFilterRegistry $codeCoverageFilterRegistry;
  78762. public function __construct(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry)
  78763. {
  78764. $this->configuration = $configuration;
  78765. $this->codeCoverageFilterRegistry = $codeCoverageFilterRegistry;
  78766. }
  78767. /**
  78768. * @throws NoActiveTimerException
  78769. * @throws NoCoverageCacheDirectoryException
  78770. */
  78771. public function execute(): \PHPUnit\TextUI\Command\Result
  78772. {
  78773. if (!$this->configuration->hasCoverageCacheDirectory()) {
  78774. return \PHPUnit\TextUI\Command\Result::from('Cache for static analysis has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE);
  78775. }
  78776. $this->codeCoverageFilterRegistry->init($this->configuration, \true);
  78777. if (!$this->codeCoverageFilterRegistry->configured()) {
  78778. return \PHPUnit\TextUI\Command\Result::from('Filter for code coverage has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE);
  78779. }
  78780. $timer = new Timer();
  78781. $timer->start();
  78782. print 'Warming cache for static analysis ... ';
  78783. (new CacheWarmer())->warmCache($this->configuration->coverageCacheDirectory(), !$this->configuration->disableCodeCoverageIgnore(), $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), $this->codeCoverageFilterRegistry->get());
  78784. printf('[%s]%s', $timer->stop()->asString(), PHP_EOL);
  78785. return \PHPUnit\TextUI\Command\Result::from();
  78786. }
  78787. }
  78788. <?php
  78789. declare (strict_types=1);
  78790. /*
  78791. * This file is part of PHPUnit.
  78792. *
  78793. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78794. *
  78795. * For the full copyright and license information, please view the LICENSE
  78796. * file that was distributed with this source code.
  78797. */
  78798. namespace PHPUnit\TextUI\Command;
  78799. /**
  78800. * @psalm-immutable
  78801. *
  78802. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78803. *
  78804. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78805. */
  78806. final class Result
  78807. {
  78808. public const SUCCESS = 0;
  78809. public const FAILURE = 1;
  78810. public const EXCEPTION = 2;
  78811. public const CRASH = 255;
  78812. private readonly string $output;
  78813. private readonly int $shellExitCode;
  78814. public static function from(string $output = '', int $shellExitCode = self::SUCCESS): self
  78815. {
  78816. return new self($output, $shellExitCode);
  78817. }
  78818. private function __construct(string $output, int $shellExitCode)
  78819. {
  78820. $this->output = $output;
  78821. $this->shellExitCode = $shellExitCode;
  78822. }
  78823. public function output(): string
  78824. {
  78825. return $this->output;
  78826. }
  78827. public function shellExitCode(): int
  78828. {
  78829. return $this->shellExitCode;
  78830. }
  78831. }
  78832. <?php
  78833. declare (strict_types=1);
  78834. /*
  78835. * This file is part of PHPUnit.
  78836. *
  78837. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78838. *
  78839. * For the full copyright and license information, please view the LICENSE
  78840. * file that was distributed with this source code.
  78841. */
  78842. namespace PHPUnit\TextUI\Configuration;
  78843. use PHPUnit\TextUI\CliArguments\Builder as CliConfigurationBuilder;
  78844. use PHPUnit\TextUI\CliArguments\Exception as CliConfigurationException;
  78845. use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
  78846. use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration;
  78847. use PHPUnit\TextUI\XmlConfiguration\Exception as XmlConfigurationException;
  78848. use PHPUnit\TextUI\XmlConfiguration\Loader;
  78849. /**
  78850. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78851. *
  78852. * @codeCoverageIgnore
  78853. */
  78854. final class Builder
  78855. {
  78856. /**
  78857. * @throws ConfigurationCannotBeBuiltException
  78858. */
  78859. public function build(array $argv): \PHPUnit\TextUI\Configuration\Configuration
  78860. {
  78861. try {
  78862. $cliConfiguration = (new CliConfigurationBuilder())->fromParameters($argv);
  78863. $configurationFile = (new XmlConfigurationFileFinder())->find($cliConfiguration);
  78864. $xmlConfiguration = DefaultConfiguration::create();
  78865. if ($configurationFile !== \false) {
  78866. $xmlConfiguration = (new Loader())->load($configurationFile);
  78867. }
  78868. return \PHPUnit\TextUI\Configuration\Registry::init($cliConfiguration, $xmlConfiguration);
  78869. } catch (CliConfigurationException|XmlConfigurationException $e) {
  78870. throw new \PHPUnit\TextUI\Configuration\ConfigurationCannotBeBuiltException($e->getMessage(), $e->getCode(), $e);
  78871. }
  78872. }
  78873. }
  78874. <?php
  78875. declare (strict_types=1);
  78876. /*
  78877. * This file is part of PHPUnit.
  78878. *
  78879. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  78880. *
  78881. * For the full copyright and license information, please view the LICENSE
  78882. * file that was distributed with this source code.
  78883. */
  78884. namespace PHPUnit\TextUI\CliArguments;
  78885. use const DIRECTORY_SEPARATOR;
  78886. use function array_map;
  78887. use function basename;
  78888. use function explode;
  78889. use function getcwd;
  78890. use function is_file;
  78891. use function is_numeric;
  78892. use function sprintf;
  78893. use PHPUnit\Event\Facade as EventFacade;
  78894. use PHPUnit\Runner\TestSuiteSorter;
  78895. use PHPUnit\Util\Filesystem;
  78896. use PHPUnitPHAR\SebastianBergmann\CliParser\Exception as CliParserException;
  78897. use PHPUnitPHAR\SebastianBergmann\CliParser\Parser as CliParser;
  78898. /**
  78899. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  78900. *
  78901. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  78902. */
  78903. final class Builder
  78904. {
  78905. private const LONG_OPTIONS = ['atleast-version=', 'bootstrap=', 'cache-result', 'do-not-cache-result', 'cache-directory=', 'cache-result-file=', 'check-version', 'colors==', 'columns=', 'configuration=', 'coverage-cache=', 'warm-coverage-cache', 'coverage-filter=', 'coverage-clover=', 'coverage-cobertura=', 'coverage-crap4j=', 'coverage-html=', 'coverage-php=', 'coverage-text==', 'only-summary-for-coverage-text', 'show-uncovered-for-coverage-text', 'coverage-xml=', 'path-coverage', 'disallow-test-output', 'display-incomplete', 'display-skipped', 'display-deprecations', 'display-phpunit-deprecations', 'display-errors', 'display-notices', 'display-warnings', 'default-time-limit=', 'enforce-time-limit', 'exclude-group=', 'filter=', 'generate-baseline=', 'use-baseline=', 'ignore-baseline', 'generate-configuration', 'globals-backup', 'group=', 'covers=', 'uses=', 'help', 'resolve-dependencies', 'ignore-dependencies', 'include-path=', 'list-groups', 'list-suites', 'list-tests', 'list-tests-xml=', 'log-junit=', 'log-teamcity=', 'migrate-configuration', 'no-configuration', 'no-coverage', 'no-logging', 'no-extensions', 'no-output', 'no-progress', 'no-results', 'order-by=', 'process-isolation', 'dont-report-useless-tests', 'random-order', 'random-order-seed=', 'reverse-order', 'reverse-list', 'static-backup', 'stderr', 'fail-on-deprecation', 'fail-on-phpunit-deprecation', 'fail-on-empty-test-suite', 'fail-on-incomplete', 'fail-on-notice', 'fail-on-risky', 'fail-on-skipped', 'fail-on-warning', 'stop-on-defect', 'stop-on-deprecation', 'stop-on-error', 'stop-on-failure', 'stop-on-incomplete', 'stop-on-notice', 'stop-on-risky', 'stop-on-skipped', 'stop-on-warning', 'strict-coverage', 'disable-coverage-ignore', 'strict-global-state', 'teamcity', 'testdox', 'testdox-html=', 'testdox-text=', 'test-suffix=', 'testsuite=', 'exclude-testsuite=', 'log-events-text=', 'log-events-verbose-text=', 'version', 'debug'];
  78906. private const SHORT_OPTIONS = 'd:c:h';
  78907. /**
  78908. * @psalm-var array<string, non-negative-int>
  78909. */
  78910. private array $processed = [];
  78911. /**
  78912. * @throws Exception
  78913. */
  78914. public function fromParameters(array $parameters): \PHPUnit\TextUI\CliArguments\Configuration
  78915. {
  78916. try {
  78917. $options = (new CliParser())->parse($parameters, self::SHORT_OPTIONS, self::LONG_OPTIONS);
  78918. } catch (CliParserException $e) {
  78919. throw new \PHPUnit\TextUI\CliArguments\Exception($e->getMessage(), $e->getCode(), $e);
  78920. }
  78921. $atLeastVersion = null;
  78922. $backupGlobals = null;
  78923. $backupStaticProperties = null;
  78924. $beStrictAboutChangesToGlobalState = null;
  78925. $bootstrap = null;
  78926. $cacheDirectory = null;
  78927. $cacheResult = null;
  78928. $cacheResultFile = null;
  78929. $checkVersion = \false;
  78930. $colors = null;
  78931. $columns = null;
  78932. $configuration = null;
  78933. $coverageCacheDirectory = null;
  78934. $warmCoverageCache = \false;
  78935. $coverageFilter = null;
  78936. $coverageClover = null;
  78937. $coverageCobertura = null;
  78938. $coverageCrap4J = null;
  78939. $coverageHtml = null;
  78940. $coveragePhp = null;
  78941. $coverageText = null;
  78942. $coverageTextShowUncoveredFiles = null;
  78943. $coverageTextShowOnlySummary = null;
  78944. $coverageXml = null;
  78945. $pathCoverage = null;
  78946. $defaultTimeLimit = null;
  78947. $disableCodeCoverageIgnore = null;
  78948. $disallowTestOutput = null;
  78949. $displayIncomplete = null;
  78950. $displaySkipped = null;
  78951. $displayDeprecations = null;
  78952. $displayPhpunitDeprecations = null;
  78953. $displayErrors = null;
  78954. $displayNotices = null;
  78955. $displayWarnings = null;
  78956. $enforceTimeLimit = null;
  78957. $excludeGroups = null;
  78958. $executionOrder = null;
  78959. $executionOrderDefects = null;
  78960. $failOnDeprecation = null;
  78961. $failOnPhpunitDeprecation = null;
  78962. $failOnEmptyTestSuite = null;
  78963. $failOnIncomplete = null;
  78964. $failOnNotice = null;
  78965. $failOnRisky = null;
  78966. $failOnSkipped = null;
  78967. $failOnWarning = null;
  78968. $stopOnDefect = null;
  78969. $stopOnDeprecation = null;
  78970. $stopOnError = null;
  78971. $stopOnFailure = null;
  78972. $stopOnIncomplete = null;
  78973. $stopOnNotice = null;
  78974. $stopOnRisky = null;
  78975. $stopOnSkipped = null;
  78976. $stopOnWarning = null;
  78977. $filter = null;
  78978. $generateBaseline = null;
  78979. $useBaseline = null;
  78980. $ignoreBaseline = \false;
  78981. $generateConfiguration = \false;
  78982. $migrateConfiguration = \false;
  78983. $groups = null;
  78984. $testsCovering = null;
  78985. $testsUsing = null;
  78986. $help = \false;
  78987. $includePath = null;
  78988. $iniSettings = [];
  78989. $junitLogfile = null;
  78990. $listGroups = \false;
  78991. $listSuites = \false;
  78992. $listTests = \false;
  78993. $listTestsXml = null;
  78994. $noCoverage = null;
  78995. $noExtensions = null;
  78996. $noOutput = null;
  78997. $noProgress = null;
  78998. $noResults = null;
  78999. $noLogging = null;
  79000. $processIsolation = null;
  79001. $randomOrderSeed = null;
  79002. $reportUselessTests = null;
  79003. $resolveDependencies = null;
  79004. $reverseList = null;
  79005. $stderr = null;
  79006. $strictCoverage = null;
  79007. $teamcityLogfile = null;
  79008. $testdoxHtmlFile = null;
  79009. $testdoxTextFile = null;
  79010. $testSuffixes = null;
  79011. $testSuite = null;
  79012. $excludeTestSuite = null;
  79013. $useDefaultConfiguration = \true;
  79014. $version = \false;
  79015. $logEventsText = null;
  79016. $logEventsVerboseText = null;
  79017. $printerTeamCity = null;
  79018. $printerTestDox = null;
  79019. $debug = \false;
  79020. foreach ($options[0] as $option) {
  79021. $optionAllowedMultipleTimes = \false;
  79022. switch ($option[0]) {
  79023. case '--colors':
  79024. $colors = $option[1] ?: \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO;
  79025. break;
  79026. case '--bootstrap':
  79027. $bootstrap = $option[1];
  79028. break;
  79029. case '--cache-directory':
  79030. $cacheDirectory = $option[1];
  79031. break;
  79032. case '--cache-result':
  79033. $cacheResult = \true;
  79034. break;
  79035. case '--do-not-cache-result':
  79036. $cacheResult = \false;
  79037. break;
  79038. case '--cache-result-file':
  79039. $cacheResultFile = $option[1];
  79040. break;
  79041. case '--columns':
  79042. if (is_numeric($option[1])) {
  79043. $columns = (int) $option[1];
  79044. } elseif ($option[1] === 'max') {
  79045. $columns = 'max';
  79046. }
  79047. break;
  79048. case 'c':
  79049. case '--configuration':
  79050. $configuration = $option[1];
  79051. break;
  79052. case '--coverage-cache':
  79053. $coverageCacheDirectory = $option[1];
  79054. break;
  79055. case '--warm-coverage-cache':
  79056. $warmCoverageCache = \true;
  79057. break;
  79058. case '--coverage-clover':
  79059. $coverageClover = $option[1];
  79060. break;
  79061. case '--coverage-cobertura':
  79062. $coverageCobertura = $option[1];
  79063. break;
  79064. case '--coverage-crap4j':
  79065. $coverageCrap4J = $option[1];
  79066. break;
  79067. case '--coverage-html':
  79068. $coverageHtml = $option[1];
  79069. break;
  79070. case '--coverage-php':
  79071. $coveragePhp = $option[1];
  79072. break;
  79073. case '--coverage-text':
  79074. if ($option[1] === null) {
  79075. $option[1] = 'php://stdout';
  79076. }
  79077. $coverageText = $option[1];
  79078. break;
  79079. case '--only-summary-for-coverage-text':
  79080. $coverageTextShowOnlySummary = \true;
  79081. break;
  79082. case '--show-uncovered-for-coverage-text':
  79083. $coverageTextShowUncoveredFiles = \true;
  79084. break;
  79085. case '--coverage-xml':
  79086. $coverageXml = $option[1];
  79087. break;
  79088. case '--path-coverage':
  79089. $pathCoverage = \true;
  79090. break;
  79091. case 'd':
  79092. $tmp = explode('=', $option[1]);
  79093. if (isset($tmp[0])) {
  79094. if (isset($tmp[1])) {
  79095. $iniSettings[$tmp[0]] = $tmp[1];
  79096. } else {
  79097. $iniSettings[$tmp[0]] = '1';
  79098. }
  79099. }
  79100. $optionAllowedMultipleTimes = \true;
  79101. break;
  79102. case 'h':
  79103. case '--help':
  79104. $help = \true;
  79105. break;
  79106. case '--filter':
  79107. $filter = $option[1];
  79108. break;
  79109. case '--testsuite':
  79110. $testSuite = $option[1];
  79111. break;
  79112. case '--exclude-testsuite':
  79113. $excludeTestSuite = $option[1];
  79114. break;
  79115. case '--generate-baseline':
  79116. $generateBaseline = $option[1];
  79117. if (basename($generateBaseline) === $generateBaseline) {
  79118. $generateBaseline = getcwd() . DIRECTORY_SEPARATOR . $generateBaseline;
  79119. }
  79120. break;
  79121. case '--use-baseline':
  79122. $useBaseline = $option[1];
  79123. if (basename($useBaseline) === $useBaseline && !is_file($useBaseline)) {
  79124. $useBaseline = getcwd() . DIRECTORY_SEPARATOR . $useBaseline;
  79125. }
  79126. break;
  79127. case '--ignore-baseline':
  79128. $ignoreBaseline = \true;
  79129. break;
  79130. case '--generate-configuration':
  79131. $generateConfiguration = \true;
  79132. break;
  79133. case '--migrate-configuration':
  79134. $migrateConfiguration = \true;
  79135. break;
  79136. case '--group':
  79137. $groups = explode(',', $option[1]);
  79138. break;
  79139. case '--exclude-group':
  79140. $excludeGroups = explode(',', $option[1]);
  79141. break;
  79142. case '--covers':
  79143. $testsCovering = array_map('strtolower', explode(',', $option[1]));
  79144. break;
  79145. case '--uses':
  79146. $testsUsing = array_map('strtolower', explode(',', $option[1]));
  79147. break;
  79148. case '--test-suffix':
  79149. $testSuffixes = explode(',', $option[1]);
  79150. break;
  79151. case '--include-path':
  79152. $includePath = $option[1];
  79153. break;
  79154. case '--list-groups':
  79155. $listGroups = \true;
  79156. break;
  79157. case '--list-suites':
  79158. $listSuites = \true;
  79159. break;
  79160. case '--list-tests':
  79161. $listTests = \true;
  79162. break;
  79163. case '--list-tests-xml':
  79164. $listTestsXml = $option[1];
  79165. break;
  79166. case '--log-junit':
  79167. $junitLogfile = $option[1];
  79168. break;
  79169. case '--log-teamcity':
  79170. $teamcityLogfile = $option[1];
  79171. break;
  79172. case '--order-by':
  79173. foreach (explode(',', $option[1]) as $order) {
  79174. switch ($order) {
  79175. case 'default':
  79176. $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
  79177. $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT;
  79178. $resolveDependencies = \true;
  79179. break;
  79180. case 'defects':
  79181. $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST;
  79182. break;
  79183. case 'depends':
  79184. $resolveDependencies = \true;
  79185. break;
  79186. case 'duration':
  79187. $executionOrder = TestSuiteSorter::ORDER_DURATION;
  79188. break;
  79189. case 'no-depends':
  79190. $resolveDependencies = \false;
  79191. break;
  79192. case 'random':
  79193. $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
  79194. break;
  79195. case 'reverse':
  79196. $executionOrder = TestSuiteSorter::ORDER_REVERSED;
  79197. break;
  79198. case 'size':
  79199. $executionOrder = TestSuiteSorter::ORDER_SIZE;
  79200. break;
  79201. default:
  79202. throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('unrecognized --order-by option: %s', $order));
  79203. }
  79204. }
  79205. break;
  79206. case '--process-isolation':
  79207. $processIsolation = \true;
  79208. break;
  79209. case '--stderr':
  79210. $stderr = \true;
  79211. break;
  79212. case '--fail-on-deprecation':
  79213. $failOnDeprecation = \true;
  79214. break;
  79215. case '--fail-on-phpunit-deprecation':
  79216. $failOnPhpunitDeprecation = \true;
  79217. break;
  79218. case '--fail-on-empty-test-suite':
  79219. $failOnEmptyTestSuite = \true;
  79220. break;
  79221. case '--fail-on-incomplete':
  79222. $failOnIncomplete = \true;
  79223. break;
  79224. case '--fail-on-notice':
  79225. $failOnNotice = \true;
  79226. break;
  79227. case '--fail-on-risky':
  79228. $failOnRisky = \true;
  79229. break;
  79230. case '--fail-on-skipped':
  79231. $failOnSkipped = \true;
  79232. break;
  79233. case '--fail-on-warning':
  79234. $failOnWarning = \true;
  79235. break;
  79236. case '--stop-on-defect':
  79237. $stopOnDefect = \true;
  79238. break;
  79239. case '--stop-on-deprecation':
  79240. $stopOnDeprecation = \true;
  79241. break;
  79242. case '--stop-on-error':
  79243. $stopOnError = \true;
  79244. break;
  79245. case '--stop-on-failure':
  79246. $stopOnFailure = \true;
  79247. break;
  79248. case '--stop-on-incomplete':
  79249. $stopOnIncomplete = \true;
  79250. break;
  79251. case '--stop-on-notice':
  79252. $stopOnNotice = \true;
  79253. break;
  79254. case '--stop-on-risky':
  79255. $stopOnRisky = \true;
  79256. break;
  79257. case '--stop-on-skipped':
  79258. $stopOnSkipped = \true;
  79259. break;
  79260. case '--stop-on-warning':
  79261. $stopOnWarning = \true;
  79262. break;
  79263. case '--teamcity':
  79264. $printerTeamCity = \true;
  79265. break;
  79266. case '--testdox':
  79267. $printerTestDox = \true;
  79268. break;
  79269. case '--testdox-html':
  79270. $testdoxHtmlFile = $option[1];
  79271. break;
  79272. case '--testdox-text':
  79273. $testdoxTextFile = $option[1];
  79274. break;
  79275. case '--no-configuration':
  79276. $useDefaultConfiguration = \false;
  79277. break;
  79278. case '--no-extensions':
  79279. $noExtensions = \true;
  79280. break;
  79281. case '--no-coverage':
  79282. $noCoverage = \true;
  79283. break;
  79284. case '--no-logging':
  79285. $noLogging = \true;
  79286. break;
  79287. case '--no-output':
  79288. $noOutput = \true;
  79289. break;
  79290. case '--no-progress':
  79291. $noProgress = \true;
  79292. break;
  79293. case '--no-results':
  79294. $noResults = \true;
  79295. break;
  79296. case '--globals-backup':
  79297. $backupGlobals = \true;
  79298. break;
  79299. case '--static-backup':
  79300. $backupStaticProperties = \true;
  79301. break;
  79302. case '--atleast-version':
  79303. $atLeastVersion = $option[1];
  79304. break;
  79305. case '--version':
  79306. $version = \true;
  79307. break;
  79308. case '--dont-report-useless-tests':
  79309. $reportUselessTests = \false;
  79310. break;
  79311. case '--strict-coverage':
  79312. $strictCoverage = \true;
  79313. break;
  79314. case '--disable-coverage-ignore':
  79315. $disableCodeCoverageIgnore = \true;
  79316. break;
  79317. case '--strict-global-state':
  79318. $beStrictAboutChangesToGlobalState = \true;
  79319. break;
  79320. case '--disallow-test-output':
  79321. $disallowTestOutput = \true;
  79322. break;
  79323. case '--display-incomplete':
  79324. $displayIncomplete = \true;
  79325. break;
  79326. case '--display-skipped':
  79327. $displaySkipped = \true;
  79328. break;
  79329. case '--display-deprecations':
  79330. $displayDeprecations = \true;
  79331. break;
  79332. case '--display-phpunit-deprecations':
  79333. $displayPhpunitDeprecations = \true;
  79334. break;
  79335. case '--display-errors':
  79336. $displayErrors = \true;
  79337. break;
  79338. case '--display-notices':
  79339. $displayNotices = \true;
  79340. break;
  79341. case '--display-warnings':
  79342. $displayWarnings = \true;
  79343. break;
  79344. case '--default-time-limit':
  79345. $defaultTimeLimit = (int) $option[1];
  79346. break;
  79347. case '--enforce-time-limit':
  79348. $enforceTimeLimit = \true;
  79349. break;
  79350. case '--reverse-list':
  79351. $reverseList = \true;
  79352. break;
  79353. case '--check-version':
  79354. $checkVersion = \true;
  79355. break;
  79356. case '--coverage-filter':
  79357. if ($coverageFilter === null) {
  79358. $coverageFilter = [];
  79359. }
  79360. $coverageFilter[] = $option[1];
  79361. $optionAllowedMultipleTimes = \true;
  79362. break;
  79363. case '--random-order':
  79364. $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
  79365. break;
  79366. case '--random-order-seed':
  79367. $randomOrderSeed = (int) $option[1];
  79368. break;
  79369. case '--resolve-dependencies':
  79370. $resolveDependencies = \true;
  79371. break;
  79372. case '--ignore-dependencies':
  79373. $resolveDependencies = \false;
  79374. break;
  79375. case '--reverse-order':
  79376. $executionOrder = TestSuiteSorter::ORDER_REVERSED;
  79377. break;
  79378. case '--log-events-text':
  79379. $logEventsText = Filesystem::resolveStreamOrFile($option[1]);
  79380. if ($logEventsText === \false) {
  79381. throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-text option could not be resolved', $option[1]));
  79382. }
  79383. break;
  79384. case '--log-events-verbose-text':
  79385. $logEventsVerboseText = Filesystem::resolveStreamOrFile($option[1]);
  79386. if ($logEventsVerboseText === \false) {
  79387. throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-verbose-text option could not be resolved', $option[1]));
  79388. }
  79389. break;
  79390. case '--debug':
  79391. $debug = \true;
  79392. break;
  79393. }
  79394. if (!$optionAllowedMultipleTimes) {
  79395. $this->markProcessed($option[0]);
  79396. }
  79397. }
  79398. if (empty($iniSettings)) {
  79399. $iniSettings = null;
  79400. }
  79401. if (empty($coverageFilter)) {
  79402. $coverageFilter = null;
  79403. }
  79404. return new \PHPUnit\TextUI\CliArguments\Configuration($options[1], $atLeastVersion, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $bootstrap, $cacheDirectory, $cacheResult, $cacheResultFile, $checkVersion, $colors, $columns, $configuration, $coverageClover, $coverageCobertura, $coverageCrap4J, $coverageHtml, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $coverageCacheDirectory, $warmCoverageCache, $defaultTimeLimit, $disableCodeCoverageIgnore, $disallowTestOutput, $enforceTimeLimit, $excludeGroups, $executionOrder, $executionOrderDefects, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $filter, $generateBaseline, $useBaseline, $ignoreBaseline, $generateConfiguration, $migrateConfiguration, $groups, $testsCovering, $testsUsing, $help, $includePath, $iniSettings, $junitLogfile, $listGroups, $listSuites, $listTests, $listTestsXml, $noCoverage, $noExtensions, $noOutput, $noProgress, $noResults, $noLogging, $processIsolation, $randomOrderSeed, $reportUselessTests, $resolveDependencies, $reverseList, $stderr, $strictCoverage, $teamcityLogfile, $testdoxHtmlFile, $testdoxTextFile, $testSuffixes, $testSuite, $excludeTestSuite, $useDefaultConfiguration, $displayIncomplete, $displaySkipped, $displayDeprecations, $displayPhpunitDeprecations, $displayErrors, $displayNotices, $displayWarnings, $version, $coverageFilter, $logEventsText, $logEventsVerboseText, $printerTeamCity, $printerTestDox, $debug);
  79405. }
  79406. /**
  79407. * @psalm-param non-empty-string $option
  79408. */
  79409. private function markProcessed(string $option): void
  79410. {
  79411. if (!isset($this->processed[$option])) {
  79412. $this->processed[$option] = 1;
  79413. return;
  79414. }
  79415. $this->processed[$option]++;
  79416. if ($this->processed[$option] === 2) {
  79417. EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Option %s cannot be used more than once', $option));
  79418. }
  79419. }
  79420. }
  79421. <?php
  79422. declare (strict_types=1);
  79423. /*
  79424. * This file is part of PHPUnit.
  79425. *
  79426. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  79427. *
  79428. * For the full copyright and license information, please view the LICENSE
  79429. * file that was distributed with this source code.
  79430. */
  79431. namespace PHPUnit\TextUI\CliArguments;
  79432. /**
  79433. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  79434. *
  79435. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  79436. *
  79437. * @psalm-immutable
  79438. */
  79439. final class Configuration
  79440. {
  79441. /**
  79442. * @psalm-var list<non-empty-string>
  79443. */
  79444. private readonly array $arguments;
  79445. private readonly ?string $atLeastVersion;
  79446. private readonly ?bool $backupGlobals;
  79447. private readonly ?bool $backupStaticProperties;
  79448. private readonly ?bool $beStrictAboutChangesToGlobalState;
  79449. private readonly ?string $bootstrap;
  79450. private readonly ?string $cacheDirectory;
  79451. private readonly ?bool $cacheResult;
  79452. private readonly ?string $cacheResultFile;
  79453. private readonly bool $checkVersion;
  79454. private readonly ?string $colors;
  79455. private readonly null|int|string $columns;
  79456. private readonly ?string $configurationFile;
  79457. private readonly ?array $coverageFilter;
  79458. private readonly ?string $coverageClover;
  79459. private readonly ?string $coverageCobertura;
  79460. private readonly ?string $coverageCrap4J;
  79461. private readonly ?string $coverageHtml;
  79462. private readonly ?string $coveragePhp;
  79463. private readonly ?string $coverageText;
  79464. private readonly ?bool $coverageTextShowUncoveredFiles;
  79465. private readonly ?bool $coverageTextShowOnlySummary;
  79466. private readonly ?string $coverageXml;
  79467. private readonly ?bool $pathCoverage;
  79468. private readonly ?string $coverageCacheDirectory;
  79469. private readonly bool $warmCoverageCache;
  79470. private readonly ?int $defaultTimeLimit;
  79471. private readonly ?bool $disableCodeCoverageIgnore;
  79472. private readonly ?bool $disallowTestOutput;
  79473. private readonly ?bool $enforceTimeLimit;
  79474. private readonly ?array $excludeGroups;
  79475. private readonly ?int $executionOrder;
  79476. private readonly ?int $executionOrderDefects;
  79477. private readonly ?bool $failOnDeprecation;
  79478. private readonly ?bool $failOnPhpunitDeprecation;
  79479. private readonly ?bool $failOnEmptyTestSuite;
  79480. private readonly ?bool $failOnIncomplete;
  79481. private readonly ?bool $failOnNotice;
  79482. private readonly ?bool $failOnRisky;
  79483. private readonly ?bool $failOnSkipped;
  79484. private readonly ?bool $failOnWarning;
  79485. private readonly ?bool $stopOnDefect;
  79486. private readonly ?bool $stopOnDeprecation;
  79487. private readonly ?bool $stopOnError;
  79488. private readonly ?bool $stopOnFailure;
  79489. private readonly ?bool $stopOnIncomplete;
  79490. private readonly ?bool $stopOnNotice;
  79491. private readonly ?bool $stopOnRisky;
  79492. private readonly ?bool $stopOnSkipped;
  79493. private readonly ?bool $stopOnWarning;
  79494. private readonly ?string $filter;
  79495. private readonly ?string $generateBaseline;
  79496. private readonly ?string $useBaseline;
  79497. private readonly bool $ignoreBaseline;
  79498. private readonly bool $generateConfiguration;
  79499. private readonly bool $migrateConfiguration;
  79500. private readonly ?array $groups;
  79501. private readonly ?array $testsCovering;
  79502. private readonly ?array $testsUsing;
  79503. private readonly bool $help;
  79504. private readonly ?string $includePath;
  79505. private readonly ?array $iniSettings;
  79506. private readonly ?string $junitLogfile;
  79507. private readonly bool $listGroups;
  79508. private readonly bool $listSuites;
  79509. private readonly bool $listTests;
  79510. private readonly ?string $listTestsXml;
  79511. private readonly ?bool $noCoverage;
  79512. private readonly ?bool $noExtensions;
  79513. private readonly ?bool $noOutput;
  79514. private readonly ?bool $noProgress;
  79515. private readonly ?bool $noResults;
  79516. private readonly ?bool $noLogging;
  79517. private readonly ?bool $processIsolation;
  79518. private readonly ?int $randomOrderSeed;
  79519. private readonly ?bool $reportUselessTests;
  79520. private readonly ?bool $resolveDependencies;
  79521. private readonly ?bool $reverseList;
  79522. private readonly ?bool $stderr;
  79523. private readonly ?bool $strictCoverage;
  79524. private readonly ?string $teamcityLogfile;
  79525. private readonly ?bool $teamCityPrinter;
  79526. private readonly ?string $testdoxHtmlFile;
  79527. private readonly ?string $testdoxTextFile;
  79528. private readonly ?bool $testdoxPrinter;
  79529. /**
  79530. * @psalm-var ?non-empty-list<non-empty-string>
  79531. */
  79532. private readonly ?array $testSuffixes;
  79533. private readonly ?string $testSuite;
  79534. private readonly ?string $excludeTestSuite;
  79535. private readonly bool $useDefaultConfiguration;
  79536. private readonly ?bool $displayDetailsOnIncompleteTests;
  79537. private readonly ?bool $displayDetailsOnSkippedTests;
  79538. private readonly ?bool $displayDetailsOnTestsThatTriggerDeprecations;
  79539. private readonly ?bool $displayDetailsOnPhpunitDeprecations;
  79540. private readonly ?bool $displayDetailsOnTestsThatTriggerErrors;
  79541. private readonly ?bool $displayDetailsOnTestsThatTriggerNotices;
  79542. private readonly ?bool $displayDetailsOnTestsThatTriggerWarnings;
  79543. private readonly bool $version;
  79544. private readonly ?string $logEventsText;
  79545. private readonly ?string $logEventsVerboseText;
  79546. private readonly bool $debug;
  79547. /**
  79548. * @psalm-param list<non-empty-string> $arguments
  79549. * @psalm-param ?non-empty-list<non-empty-string> $testSuffixes
  79550. */
  79551. public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, ?string $cacheResultFile, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, ?string $coverageCacheDirectory, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $stopOnDefect, ?bool $stopOnDeprecation, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnNotice, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $filter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $printerTestDox, bool $debug)
  79552. {
  79553. $this->arguments = $arguments;
  79554. $this->atLeastVersion = $atLeastVersion;
  79555. $this->backupGlobals = $backupGlobals;
  79556. $this->backupStaticProperties = $backupStaticProperties;
  79557. $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
  79558. $this->bootstrap = $bootstrap;
  79559. $this->cacheDirectory = $cacheDirectory;
  79560. $this->cacheResult = $cacheResult;
  79561. $this->cacheResultFile = $cacheResultFile;
  79562. $this->checkVersion = $checkVersion;
  79563. $this->colors = $colors;
  79564. $this->columns = $columns;
  79565. $this->configurationFile = $configurationFile;
  79566. $this->coverageFilter = $coverageFilter;
  79567. $this->coverageClover = $coverageClover;
  79568. $this->coverageCobertura = $coverageCobertura;
  79569. $this->coverageCrap4J = $coverageCrap4J;
  79570. $this->coverageHtml = $coverageHtml;
  79571. $this->coveragePhp = $coveragePhp;
  79572. $this->coverageText = $coverageText;
  79573. $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles;
  79574. $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary;
  79575. $this->coverageXml = $coverageXml;
  79576. $this->pathCoverage = $pathCoverage;
  79577. $this->coverageCacheDirectory = $coverageCacheDirectory;
  79578. $this->warmCoverageCache = $warmCoverageCache;
  79579. $this->defaultTimeLimit = $defaultTimeLimit;
  79580. $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
  79581. $this->disallowTestOutput = $disallowTestOutput;
  79582. $this->enforceTimeLimit = $enforceTimeLimit;
  79583. $this->excludeGroups = $excludeGroups;
  79584. $this->executionOrder = $executionOrder;
  79585. $this->executionOrderDefects = $executionOrderDefects;
  79586. $this->failOnDeprecation = $failOnDeprecation;
  79587. $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
  79588. $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
  79589. $this->failOnIncomplete = $failOnIncomplete;
  79590. $this->failOnNotice = $failOnNotice;
  79591. $this->failOnRisky = $failOnRisky;
  79592. $this->failOnSkipped = $failOnSkipped;
  79593. $this->failOnWarning = $failOnWarning;
  79594. $this->stopOnDefect = $stopOnDefect;
  79595. $this->stopOnDeprecation = $stopOnDeprecation;
  79596. $this->stopOnError = $stopOnError;
  79597. $this->stopOnFailure = $stopOnFailure;
  79598. $this->stopOnIncomplete = $stopOnIncomplete;
  79599. $this->stopOnNotice = $stopOnNotice;
  79600. $this->stopOnRisky = $stopOnRisky;
  79601. $this->stopOnSkipped = $stopOnSkipped;
  79602. $this->stopOnWarning = $stopOnWarning;
  79603. $this->filter = $filter;
  79604. $this->generateBaseline = $generateBaseline;
  79605. $this->useBaseline = $useBaseline;
  79606. $this->ignoreBaseline = $ignoreBaseline;
  79607. $this->generateConfiguration = $generateConfiguration;
  79608. $this->migrateConfiguration = $migrateConfiguration;
  79609. $this->groups = $groups;
  79610. $this->testsCovering = $testsCovering;
  79611. $this->testsUsing = $testsUsing;
  79612. $this->help = $help;
  79613. $this->includePath = $includePath;
  79614. $this->iniSettings = $iniSettings;
  79615. $this->junitLogfile = $junitLogfile;
  79616. $this->listGroups = $listGroups;
  79617. $this->listSuites = $listSuites;
  79618. $this->listTests = $listTests;
  79619. $this->listTestsXml = $listTestsXml;
  79620. $this->noCoverage = $noCoverage;
  79621. $this->noExtensions = $noExtensions;
  79622. $this->noOutput = $noOutput;
  79623. $this->noProgress = $noProgress;
  79624. $this->noResults = $noResults;
  79625. $this->noLogging = $noLogging;
  79626. $this->processIsolation = $processIsolation;
  79627. $this->randomOrderSeed = $randomOrderSeed;
  79628. $this->reportUselessTests = $reportUselessTests;
  79629. $this->resolveDependencies = $resolveDependencies;
  79630. $this->reverseList = $reverseList;
  79631. $this->stderr = $stderr;
  79632. $this->strictCoverage = $strictCoverage;
  79633. $this->teamcityLogfile = $teamcityLogfile;
  79634. $this->testdoxHtmlFile = $testdoxHtmlFile;
  79635. $this->testdoxTextFile = $testdoxTextFile;
  79636. $this->testSuffixes = $testSuffixes;
  79637. $this->testSuite = $testSuite;
  79638. $this->excludeTestSuite = $excludeTestSuite;
  79639. $this->useDefaultConfiguration = $useDefaultConfiguration;
  79640. $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
  79641. $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
  79642. $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
  79643. $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
  79644. $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
  79645. $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
  79646. $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
  79647. $this->version = $version;
  79648. $this->logEventsText = $logEventsText;
  79649. $this->logEventsVerboseText = $logEventsVerboseText;
  79650. $this->teamCityPrinter = $printerTeamCity;
  79651. $this->testdoxPrinter = $printerTestDox;
  79652. $this->debug = $debug;
  79653. }
  79654. /**
  79655. * @psalm-return list<non-empty-string>
  79656. */
  79657. public function arguments(): array
  79658. {
  79659. return $this->arguments;
  79660. }
  79661. /**
  79662. * @psalm-assert-if-true !null $this->atLeastVersion
  79663. */
  79664. public function hasAtLeastVersion(): bool
  79665. {
  79666. return $this->atLeastVersion !== null;
  79667. }
  79668. /**
  79669. * @throws Exception
  79670. */
  79671. public function atLeastVersion(): string
  79672. {
  79673. if (!$this->hasAtLeastVersion()) {
  79674. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79675. }
  79676. return $this->atLeastVersion;
  79677. }
  79678. /**
  79679. * @psalm-assert-if-true !null $this->backupGlobals
  79680. */
  79681. public function hasBackupGlobals(): bool
  79682. {
  79683. return $this->backupGlobals !== null;
  79684. }
  79685. /**
  79686. * @throws Exception
  79687. */
  79688. public function backupGlobals(): bool
  79689. {
  79690. if (!$this->hasBackupGlobals()) {
  79691. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79692. }
  79693. return $this->backupGlobals;
  79694. }
  79695. /**
  79696. * @psalm-assert-if-true !null $this->backupStaticProperties
  79697. */
  79698. public function hasBackupStaticProperties(): bool
  79699. {
  79700. return $this->backupStaticProperties !== null;
  79701. }
  79702. /**
  79703. * @throws Exception
  79704. */
  79705. public function backupStaticProperties(): bool
  79706. {
  79707. if (!$this->hasBackupStaticProperties()) {
  79708. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79709. }
  79710. return $this->backupStaticProperties;
  79711. }
  79712. /**
  79713. * @psalm-assert-if-true !null $this->beStrictAboutChangesToGlobalState
  79714. */
  79715. public function hasBeStrictAboutChangesToGlobalState(): bool
  79716. {
  79717. return $this->beStrictAboutChangesToGlobalState !== null;
  79718. }
  79719. /**
  79720. * @throws Exception
  79721. */
  79722. public function beStrictAboutChangesToGlobalState(): bool
  79723. {
  79724. if (!$this->hasBeStrictAboutChangesToGlobalState()) {
  79725. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79726. }
  79727. return $this->beStrictAboutChangesToGlobalState;
  79728. }
  79729. /**
  79730. * @psalm-assert-if-true !null $this->bootstrap
  79731. */
  79732. public function hasBootstrap(): bool
  79733. {
  79734. return $this->bootstrap !== null;
  79735. }
  79736. /**
  79737. * @throws Exception
  79738. */
  79739. public function bootstrap(): string
  79740. {
  79741. if (!$this->hasBootstrap()) {
  79742. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79743. }
  79744. return $this->bootstrap;
  79745. }
  79746. /**
  79747. * @psalm-assert-if-true !null $this->cacheDirectory
  79748. */
  79749. public function hasCacheDirectory(): bool
  79750. {
  79751. return $this->cacheDirectory !== null;
  79752. }
  79753. /**
  79754. * @throws Exception
  79755. */
  79756. public function cacheDirectory(): string
  79757. {
  79758. if (!$this->hasCacheDirectory()) {
  79759. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79760. }
  79761. return $this->cacheDirectory;
  79762. }
  79763. /**
  79764. * @psalm-assert-if-true !null $this->cacheResult
  79765. */
  79766. public function hasCacheResult(): bool
  79767. {
  79768. return $this->cacheResult !== null;
  79769. }
  79770. /**
  79771. * @throws Exception
  79772. */
  79773. public function cacheResult(): bool
  79774. {
  79775. if (!$this->hasCacheResult()) {
  79776. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79777. }
  79778. return $this->cacheResult;
  79779. }
  79780. /**
  79781. * @psalm-assert-if-true !null $this->cacheResultFile
  79782. *
  79783. * @deprecated
  79784. */
  79785. public function hasCacheResultFile(): bool
  79786. {
  79787. return $this->cacheResultFile !== null;
  79788. }
  79789. /**
  79790. * @throws Exception
  79791. *
  79792. * @deprecated
  79793. */
  79794. public function cacheResultFile(): string
  79795. {
  79796. if (!$this->hasCacheResultFile()) {
  79797. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79798. }
  79799. return $this->cacheResultFile;
  79800. }
  79801. public function checkVersion(): bool
  79802. {
  79803. return $this->checkVersion;
  79804. }
  79805. /**
  79806. * @psalm-assert-if-true !null $this->colors
  79807. */
  79808. public function hasColors(): bool
  79809. {
  79810. return $this->colors !== null;
  79811. }
  79812. /**
  79813. * @throws Exception
  79814. */
  79815. public function colors(): string
  79816. {
  79817. if (!$this->hasColors()) {
  79818. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79819. }
  79820. return $this->colors;
  79821. }
  79822. /**
  79823. * @psalm-assert-if-true !null $this->columns
  79824. */
  79825. public function hasColumns(): bool
  79826. {
  79827. return $this->columns !== null;
  79828. }
  79829. /**
  79830. * @throws Exception
  79831. */
  79832. public function columns(): int|string
  79833. {
  79834. if (!$this->hasColumns()) {
  79835. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79836. }
  79837. return $this->columns;
  79838. }
  79839. /**
  79840. * @psalm-assert-if-true !null $this->configurationFile
  79841. */
  79842. public function hasConfigurationFile(): bool
  79843. {
  79844. return $this->configurationFile !== null;
  79845. }
  79846. /**
  79847. * @throws Exception
  79848. */
  79849. public function configurationFile(): string
  79850. {
  79851. if (!$this->hasConfigurationFile()) {
  79852. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79853. }
  79854. return $this->configurationFile;
  79855. }
  79856. /**
  79857. * @psalm-assert-if-true !null $this->coverageFilter
  79858. */
  79859. public function hasCoverageFilter(): bool
  79860. {
  79861. return $this->coverageFilter !== null;
  79862. }
  79863. /**
  79864. * @throws Exception
  79865. */
  79866. public function coverageFilter(): array
  79867. {
  79868. if (!$this->hasCoverageFilter()) {
  79869. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79870. }
  79871. return $this->coverageFilter;
  79872. }
  79873. /**
  79874. * @psalm-assert-if-true !null $this->coverageClover
  79875. */
  79876. public function hasCoverageClover(): bool
  79877. {
  79878. return $this->coverageClover !== null;
  79879. }
  79880. /**
  79881. * @throws Exception
  79882. */
  79883. public function coverageClover(): string
  79884. {
  79885. if (!$this->hasCoverageClover()) {
  79886. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79887. }
  79888. return $this->coverageClover;
  79889. }
  79890. /**
  79891. * @psalm-assert-if-true !null $this->coverageCobertura
  79892. */
  79893. public function hasCoverageCobertura(): bool
  79894. {
  79895. return $this->coverageCobertura !== null;
  79896. }
  79897. /**
  79898. * @throws Exception
  79899. */
  79900. public function coverageCobertura(): string
  79901. {
  79902. if (!$this->hasCoverageCobertura()) {
  79903. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79904. }
  79905. return $this->coverageCobertura;
  79906. }
  79907. /**
  79908. * @psalm-assert-if-true !null $this->coverageCrap4J
  79909. */
  79910. public function hasCoverageCrap4J(): bool
  79911. {
  79912. return $this->coverageCrap4J !== null;
  79913. }
  79914. /**
  79915. * @throws Exception
  79916. */
  79917. public function coverageCrap4J(): string
  79918. {
  79919. if (!$this->hasCoverageCrap4J()) {
  79920. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79921. }
  79922. return $this->coverageCrap4J;
  79923. }
  79924. /**
  79925. * @psalm-assert-if-true !null $this->coverageHtml
  79926. */
  79927. public function hasCoverageHtml(): bool
  79928. {
  79929. return $this->coverageHtml !== null;
  79930. }
  79931. /**
  79932. * @throws Exception
  79933. */
  79934. public function coverageHtml(): string
  79935. {
  79936. if (!$this->hasCoverageHtml()) {
  79937. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79938. }
  79939. return $this->coverageHtml;
  79940. }
  79941. /**
  79942. * @psalm-assert-if-true !null $this->coveragePhp
  79943. */
  79944. public function hasCoveragePhp(): bool
  79945. {
  79946. return $this->coveragePhp !== null;
  79947. }
  79948. /**
  79949. * @throws Exception
  79950. */
  79951. public function coveragePhp(): string
  79952. {
  79953. if (!$this->hasCoveragePhp()) {
  79954. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79955. }
  79956. return $this->coveragePhp;
  79957. }
  79958. /**
  79959. * @psalm-assert-if-true !null $this->coverageText
  79960. */
  79961. public function hasCoverageText(): bool
  79962. {
  79963. return $this->coverageText !== null;
  79964. }
  79965. /**
  79966. * @throws Exception
  79967. */
  79968. public function coverageText(): string
  79969. {
  79970. if (!$this->hasCoverageText()) {
  79971. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79972. }
  79973. return $this->coverageText;
  79974. }
  79975. /**
  79976. * @psalm-assert-if-true !null $this->coverageTextShowUncoveredFiles
  79977. */
  79978. public function hasCoverageTextShowUncoveredFiles(): bool
  79979. {
  79980. return $this->coverageTextShowUncoveredFiles !== null;
  79981. }
  79982. /**
  79983. * @throws Exception
  79984. */
  79985. public function coverageTextShowUncoveredFiles(): bool
  79986. {
  79987. if (!$this->hasCoverageTextShowUncoveredFiles()) {
  79988. throw new \PHPUnit\TextUI\CliArguments\Exception();
  79989. }
  79990. return $this->coverageTextShowUncoveredFiles;
  79991. }
  79992. /**
  79993. * @psalm-assert-if-true !null $this->coverageTextShowOnlySummary
  79994. */
  79995. public function hasCoverageTextShowOnlySummary(): bool
  79996. {
  79997. return $this->coverageTextShowOnlySummary !== null;
  79998. }
  79999. /**
  80000. * @throws Exception
  80001. */
  80002. public function coverageTextShowOnlySummary(): bool
  80003. {
  80004. if (!$this->hasCoverageTextShowOnlySummary()) {
  80005. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80006. }
  80007. return $this->coverageTextShowOnlySummary;
  80008. }
  80009. /**
  80010. * @psalm-assert-if-true !null $this->coverageXml
  80011. */
  80012. public function hasCoverageXml(): bool
  80013. {
  80014. return $this->coverageXml !== null;
  80015. }
  80016. /**
  80017. * @throws Exception
  80018. */
  80019. public function coverageXml(): string
  80020. {
  80021. if (!$this->hasCoverageXml()) {
  80022. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80023. }
  80024. return $this->coverageXml;
  80025. }
  80026. /**
  80027. * @psalm-assert-if-true !null $this->pathCoverage
  80028. */
  80029. public function hasPathCoverage(): bool
  80030. {
  80031. return $this->pathCoverage !== null;
  80032. }
  80033. /**
  80034. * @throws Exception
  80035. */
  80036. public function pathCoverage(): bool
  80037. {
  80038. if (!$this->hasPathCoverage()) {
  80039. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80040. }
  80041. return $this->pathCoverage;
  80042. }
  80043. /**
  80044. * @psalm-assert-if-true !null $this->coverageCacheDirectory
  80045. *
  80046. * @deprecated
  80047. */
  80048. public function hasCoverageCacheDirectory(): bool
  80049. {
  80050. return $this->coverageCacheDirectory !== null;
  80051. }
  80052. /**
  80053. * @throws Exception
  80054. *
  80055. * @deprecated
  80056. */
  80057. public function coverageCacheDirectory(): string
  80058. {
  80059. if (!$this->hasCoverageCacheDirectory()) {
  80060. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80061. }
  80062. return $this->coverageCacheDirectory;
  80063. }
  80064. public function warmCoverageCache(): bool
  80065. {
  80066. return $this->warmCoverageCache;
  80067. }
  80068. /**
  80069. * @psalm-assert-if-true !null $this->defaultTimeLimit
  80070. */
  80071. public function hasDefaultTimeLimit(): bool
  80072. {
  80073. return $this->defaultTimeLimit !== null;
  80074. }
  80075. /**
  80076. * @throws Exception
  80077. */
  80078. public function defaultTimeLimit(): int
  80079. {
  80080. if (!$this->hasDefaultTimeLimit()) {
  80081. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80082. }
  80083. return $this->defaultTimeLimit;
  80084. }
  80085. /**
  80086. * @psalm-assert-if-true !null $this->disableCodeCoverageIgnore
  80087. */
  80088. public function hasDisableCodeCoverageIgnore(): bool
  80089. {
  80090. return $this->disableCodeCoverageIgnore !== null;
  80091. }
  80092. /**
  80093. * @throws Exception
  80094. */
  80095. public function disableCodeCoverageIgnore(): bool
  80096. {
  80097. if (!$this->hasDisableCodeCoverageIgnore()) {
  80098. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80099. }
  80100. return $this->disableCodeCoverageIgnore;
  80101. }
  80102. /**
  80103. * @psalm-assert-if-true !null $this->disallowTestOutput
  80104. */
  80105. public function hasDisallowTestOutput(): bool
  80106. {
  80107. return $this->disallowTestOutput !== null;
  80108. }
  80109. /**
  80110. * @throws Exception
  80111. */
  80112. public function disallowTestOutput(): bool
  80113. {
  80114. if (!$this->hasDisallowTestOutput()) {
  80115. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80116. }
  80117. return $this->disallowTestOutput;
  80118. }
  80119. /**
  80120. * @psalm-assert-if-true !null $this->enforceTimeLimit
  80121. */
  80122. public function hasEnforceTimeLimit(): bool
  80123. {
  80124. return $this->enforceTimeLimit !== null;
  80125. }
  80126. /**
  80127. * @throws Exception
  80128. */
  80129. public function enforceTimeLimit(): bool
  80130. {
  80131. if (!$this->hasEnforceTimeLimit()) {
  80132. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80133. }
  80134. return $this->enforceTimeLimit;
  80135. }
  80136. /**
  80137. * @psalm-assert-if-true !null $this->excludeGroups
  80138. */
  80139. public function hasExcludeGroups(): bool
  80140. {
  80141. return $this->excludeGroups !== null;
  80142. }
  80143. /**
  80144. * @throws Exception
  80145. */
  80146. public function excludeGroups(): array
  80147. {
  80148. if (!$this->hasExcludeGroups()) {
  80149. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80150. }
  80151. return $this->excludeGroups;
  80152. }
  80153. /**
  80154. * @psalm-assert-if-true !null $this->executionOrder
  80155. */
  80156. public function hasExecutionOrder(): bool
  80157. {
  80158. return $this->executionOrder !== null;
  80159. }
  80160. /**
  80161. * @throws Exception
  80162. */
  80163. public function executionOrder(): int
  80164. {
  80165. if (!$this->hasExecutionOrder()) {
  80166. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80167. }
  80168. return $this->executionOrder;
  80169. }
  80170. /**
  80171. * @psalm-assert-if-true !null $this->executionOrderDefects
  80172. */
  80173. public function hasExecutionOrderDefects(): bool
  80174. {
  80175. return $this->executionOrderDefects !== null;
  80176. }
  80177. /**
  80178. * @throws Exception
  80179. */
  80180. public function executionOrderDefects(): int
  80181. {
  80182. if (!$this->hasExecutionOrderDefects()) {
  80183. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80184. }
  80185. return $this->executionOrderDefects;
  80186. }
  80187. /**
  80188. * @psalm-assert-if-true !null $this->failOnDeprecation
  80189. */
  80190. public function hasFailOnDeprecation(): bool
  80191. {
  80192. return $this->failOnDeprecation !== null;
  80193. }
  80194. /**
  80195. * @throws Exception
  80196. */
  80197. public function failOnDeprecation(): bool
  80198. {
  80199. if (!$this->hasFailOnDeprecation()) {
  80200. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80201. }
  80202. return $this->failOnDeprecation;
  80203. }
  80204. /**
  80205. * @psalm-assert-if-true !null $this->failOnPhpunitDeprecation
  80206. */
  80207. public function hasFailOnPhpunitDeprecation(): bool
  80208. {
  80209. return $this->failOnPhpunitDeprecation !== null;
  80210. }
  80211. /**
  80212. * @throws Exception
  80213. */
  80214. public function failOnPhpunitDeprecation(): bool
  80215. {
  80216. if (!$this->hasFailOnPhpunitDeprecation()) {
  80217. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80218. }
  80219. return $this->failOnPhpunitDeprecation;
  80220. }
  80221. /**
  80222. * @psalm-assert-if-true !null $this->failOnEmptyTestSuite
  80223. */
  80224. public function hasFailOnEmptyTestSuite(): bool
  80225. {
  80226. return $this->failOnEmptyTestSuite !== null;
  80227. }
  80228. /**
  80229. * @throws Exception
  80230. */
  80231. public function failOnEmptyTestSuite(): bool
  80232. {
  80233. if (!$this->hasFailOnEmptyTestSuite()) {
  80234. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80235. }
  80236. return $this->failOnEmptyTestSuite;
  80237. }
  80238. /**
  80239. * @psalm-assert-if-true !null $this->failOnIncomplete
  80240. */
  80241. public function hasFailOnIncomplete(): bool
  80242. {
  80243. return $this->failOnIncomplete !== null;
  80244. }
  80245. /**
  80246. * @throws Exception
  80247. */
  80248. public function failOnIncomplete(): bool
  80249. {
  80250. if (!$this->hasFailOnIncomplete()) {
  80251. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80252. }
  80253. return $this->failOnIncomplete;
  80254. }
  80255. /**
  80256. * @psalm-assert-if-true !null $this->failOnNotice
  80257. */
  80258. public function hasFailOnNotice(): bool
  80259. {
  80260. return $this->failOnNotice !== null;
  80261. }
  80262. /**
  80263. * @throws Exception
  80264. */
  80265. public function failOnNotice(): bool
  80266. {
  80267. if (!$this->hasFailOnNotice()) {
  80268. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80269. }
  80270. return $this->failOnNotice;
  80271. }
  80272. /**
  80273. * @psalm-assert-if-true !null $this->failOnRisky
  80274. */
  80275. public function hasFailOnRisky(): bool
  80276. {
  80277. return $this->failOnRisky !== null;
  80278. }
  80279. /**
  80280. * @throws Exception
  80281. */
  80282. public function failOnRisky(): bool
  80283. {
  80284. if (!$this->hasFailOnRisky()) {
  80285. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80286. }
  80287. return $this->failOnRisky;
  80288. }
  80289. /**
  80290. * @psalm-assert-if-true !null $this->failOnSkipped
  80291. */
  80292. public function hasFailOnSkipped(): bool
  80293. {
  80294. return $this->failOnSkipped !== null;
  80295. }
  80296. /**
  80297. * @throws Exception
  80298. */
  80299. public function failOnSkipped(): bool
  80300. {
  80301. if (!$this->hasFailOnSkipped()) {
  80302. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80303. }
  80304. return $this->failOnSkipped;
  80305. }
  80306. /**
  80307. * @psalm-assert-if-true !null $this->failOnWarning
  80308. */
  80309. public function hasFailOnWarning(): bool
  80310. {
  80311. return $this->failOnWarning !== null;
  80312. }
  80313. /**
  80314. * @throws Exception
  80315. */
  80316. public function failOnWarning(): bool
  80317. {
  80318. if (!$this->hasFailOnWarning()) {
  80319. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80320. }
  80321. return $this->failOnWarning;
  80322. }
  80323. /**
  80324. * @psalm-assert-if-true !null $this->stopOnDefect
  80325. */
  80326. public function hasStopOnDefect(): bool
  80327. {
  80328. return $this->stopOnDefect !== null;
  80329. }
  80330. /**
  80331. * @throws Exception
  80332. */
  80333. public function stopOnDefect(): bool
  80334. {
  80335. if (!$this->hasStopOnDefect()) {
  80336. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80337. }
  80338. return $this->stopOnDefect;
  80339. }
  80340. /**
  80341. * @psalm-assert-if-true !null $this->stopOnDeprecation
  80342. */
  80343. public function hasStopOnDeprecation(): bool
  80344. {
  80345. return $this->stopOnDeprecation !== null;
  80346. }
  80347. /**
  80348. * @throws Exception
  80349. */
  80350. public function stopOnDeprecation(): bool
  80351. {
  80352. if (!$this->hasStopOnDeprecation()) {
  80353. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80354. }
  80355. return $this->stopOnDeprecation;
  80356. }
  80357. /**
  80358. * @psalm-assert-if-true !null $this->stopOnError
  80359. */
  80360. public function hasStopOnError(): bool
  80361. {
  80362. return $this->stopOnError !== null;
  80363. }
  80364. /**
  80365. * @throws Exception
  80366. */
  80367. public function stopOnError(): bool
  80368. {
  80369. if (!$this->hasStopOnError()) {
  80370. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80371. }
  80372. return $this->stopOnError;
  80373. }
  80374. /**
  80375. * @psalm-assert-if-true !null $this->stopOnFailure
  80376. */
  80377. public function hasStopOnFailure(): bool
  80378. {
  80379. return $this->stopOnFailure !== null;
  80380. }
  80381. /**
  80382. * @throws Exception
  80383. */
  80384. public function stopOnFailure(): bool
  80385. {
  80386. if (!$this->hasStopOnFailure()) {
  80387. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80388. }
  80389. return $this->stopOnFailure;
  80390. }
  80391. /**
  80392. * @psalm-assert-if-true !null $this->stopOnIncomplete
  80393. */
  80394. public function hasStopOnIncomplete(): bool
  80395. {
  80396. return $this->stopOnIncomplete !== null;
  80397. }
  80398. /**
  80399. * @throws Exception
  80400. */
  80401. public function stopOnIncomplete(): bool
  80402. {
  80403. if (!$this->hasStopOnIncomplete()) {
  80404. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80405. }
  80406. return $this->stopOnIncomplete;
  80407. }
  80408. /**
  80409. * @psalm-assert-if-true !null $this->stopOnNotice
  80410. */
  80411. public function hasStopOnNotice(): bool
  80412. {
  80413. return $this->stopOnNotice !== null;
  80414. }
  80415. /**
  80416. * @throws Exception
  80417. */
  80418. public function stopOnNotice(): bool
  80419. {
  80420. if (!$this->hasStopOnNotice()) {
  80421. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80422. }
  80423. return $this->stopOnNotice;
  80424. }
  80425. /**
  80426. * @psalm-assert-if-true !null $this->stopOnRisky
  80427. */
  80428. public function hasStopOnRisky(): bool
  80429. {
  80430. return $this->stopOnRisky !== null;
  80431. }
  80432. /**
  80433. * @throws Exception
  80434. */
  80435. public function stopOnRisky(): bool
  80436. {
  80437. if (!$this->hasStopOnRisky()) {
  80438. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80439. }
  80440. return $this->stopOnRisky;
  80441. }
  80442. /**
  80443. * @psalm-assert-if-true !null $this->stopOnSkipped
  80444. */
  80445. public function hasStopOnSkipped(): bool
  80446. {
  80447. return $this->stopOnSkipped !== null;
  80448. }
  80449. /**
  80450. * @throws Exception
  80451. */
  80452. public function stopOnSkipped(): bool
  80453. {
  80454. if (!$this->hasStopOnSkipped()) {
  80455. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80456. }
  80457. return $this->stopOnSkipped;
  80458. }
  80459. /**
  80460. * @psalm-assert-if-true !null $this->stopOnWarning
  80461. */
  80462. public function hasStopOnWarning(): bool
  80463. {
  80464. return $this->stopOnWarning !== null;
  80465. }
  80466. /**
  80467. * @throws Exception
  80468. */
  80469. public function stopOnWarning(): bool
  80470. {
  80471. if (!$this->hasStopOnWarning()) {
  80472. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80473. }
  80474. return $this->stopOnWarning;
  80475. }
  80476. /**
  80477. * @psalm-assert-if-true !null $this->filter
  80478. */
  80479. public function hasFilter(): bool
  80480. {
  80481. return $this->filter !== null;
  80482. }
  80483. /**
  80484. * @throws Exception
  80485. */
  80486. public function filter(): string
  80487. {
  80488. if (!$this->hasFilter()) {
  80489. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80490. }
  80491. return $this->filter;
  80492. }
  80493. /**
  80494. * @psalm-assert-if-true !null $this->generateBaseline
  80495. */
  80496. public function hasGenerateBaseline(): bool
  80497. {
  80498. return $this->generateBaseline !== null;
  80499. }
  80500. /**
  80501. * @throws Exception
  80502. */
  80503. public function generateBaseline(): string
  80504. {
  80505. if (!$this->hasGenerateBaseline()) {
  80506. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80507. }
  80508. return $this->generateBaseline;
  80509. }
  80510. /**
  80511. * @psalm-assert-if-true !null $this->useBaseline
  80512. */
  80513. public function hasUseBaseline(): bool
  80514. {
  80515. return $this->useBaseline !== null;
  80516. }
  80517. /**
  80518. * @throws Exception
  80519. */
  80520. public function useBaseline(): string
  80521. {
  80522. if (!$this->hasUseBaseline()) {
  80523. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80524. }
  80525. return $this->useBaseline;
  80526. }
  80527. public function ignoreBaseline(): bool
  80528. {
  80529. return $this->ignoreBaseline;
  80530. }
  80531. public function generateConfiguration(): bool
  80532. {
  80533. return $this->generateConfiguration;
  80534. }
  80535. public function migrateConfiguration(): bool
  80536. {
  80537. return $this->migrateConfiguration;
  80538. }
  80539. /**
  80540. * @psalm-assert-if-true !null $this->groups
  80541. */
  80542. public function hasGroups(): bool
  80543. {
  80544. return $this->groups !== null;
  80545. }
  80546. /**
  80547. * @throws Exception
  80548. */
  80549. public function groups(): array
  80550. {
  80551. if (!$this->hasGroups()) {
  80552. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80553. }
  80554. return $this->groups;
  80555. }
  80556. /**
  80557. * @psalm-assert-if-true !null $this->testsCovering
  80558. */
  80559. public function hasTestsCovering(): bool
  80560. {
  80561. return $this->testsCovering !== null;
  80562. }
  80563. /**
  80564. * @throws Exception
  80565. */
  80566. public function testsCovering(): array
  80567. {
  80568. if (!$this->hasTestsCovering()) {
  80569. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80570. }
  80571. return $this->testsCovering;
  80572. }
  80573. /**
  80574. * @psalm-assert-if-true !null $this->testsUsing
  80575. */
  80576. public function hasTestsUsing(): bool
  80577. {
  80578. return $this->testsUsing !== null;
  80579. }
  80580. /**
  80581. * @throws Exception
  80582. */
  80583. public function testsUsing(): array
  80584. {
  80585. if (!$this->hasTestsUsing()) {
  80586. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80587. }
  80588. return $this->testsUsing;
  80589. }
  80590. public function help(): bool
  80591. {
  80592. return $this->help;
  80593. }
  80594. /**
  80595. * @psalm-assert-if-true !null $this->includePath
  80596. */
  80597. public function hasIncludePath(): bool
  80598. {
  80599. return $this->includePath !== null;
  80600. }
  80601. /**
  80602. * @throws Exception
  80603. */
  80604. public function includePath(): string
  80605. {
  80606. if (!$this->hasIncludePath()) {
  80607. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80608. }
  80609. return $this->includePath;
  80610. }
  80611. /**
  80612. * @psalm-assert-if-true !null $this->iniSettings
  80613. */
  80614. public function hasIniSettings(): bool
  80615. {
  80616. return $this->iniSettings !== null;
  80617. }
  80618. /**
  80619. * @throws Exception
  80620. */
  80621. public function iniSettings(): array
  80622. {
  80623. if (!$this->hasIniSettings()) {
  80624. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80625. }
  80626. return $this->iniSettings;
  80627. }
  80628. /**
  80629. * @psalm-assert-if-true !null $this->junitLogfile
  80630. */
  80631. public function hasJunitLogfile(): bool
  80632. {
  80633. return $this->junitLogfile !== null;
  80634. }
  80635. /**
  80636. * @throws Exception
  80637. */
  80638. public function junitLogfile(): string
  80639. {
  80640. if (!$this->hasJunitLogfile()) {
  80641. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80642. }
  80643. return $this->junitLogfile;
  80644. }
  80645. public function listGroups(): bool
  80646. {
  80647. return $this->listGroups;
  80648. }
  80649. public function listSuites(): bool
  80650. {
  80651. return $this->listSuites;
  80652. }
  80653. public function listTests(): bool
  80654. {
  80655. return $this->listTests;
  80656. }
  80657. /**
  80658. * @psalm-assert-if-true !null $this->listTestsXml
  80659. */
  80660. public function hasListTestsXml(): bool
  80661. {
  80662. return $this->listTestsXml !== null;
  80663. }
  80664. /**
  80665. * @throws Exception
  80666. */
  80667. public function listTestsXml(): string
  80668. {
  80669. if (!$this->hasListTestsXml()) {
  80670. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80671. }
  80672. return $this->listTestsXml;
  80673. }
  80674. /**
  80675. * @psalm-assert-if-true !null $this->noCoverage
  80676. */
  80677. public function hasNoCoverage(): bool
  80678. {
  80679. return $this->noCoverage !== null;
  80680. }
  80681. /**
  80682. * @throws Exception
  80683. */
  80684. public function noCoverage(): bool
  80685. {
  80686. if (!$this->hasNoCoverage()) {
  80687. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80688. }
  80689. return $this->noCoverage;
  80690. }
  80691. /**
  80692. * @psalm-assert-if-true !null $this->noExtensions
  80693. */
  80694. public function hasNoExtensions(): bool
  80695. {
  80696. return $this->noExtensions !== null;
  80697. }
  80698. /**
  80699. * @throws Exception
  80700. */
  80701. public function noExtensions(): bool
  80702. {
  80703. if (!$this->hasNoExtensions()) {
  80704. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80705. }
  80706. return $this->noExtensions;
  80707. }
  80708. /**
  80709. * @psalm-assert-if-true !null $this->noOutput
  80710. */
  80711. public function hasNoOutput(): bool
  80712. {
  80713. return $this->noOutput !== null;
  80714. }
  80715. /**
  80716. * @throws Exception
  80717. */
  80718. public function noOutput(): bool
  80719. {
  80720. if ($this->noOutput === null) {
  80721. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80722. }
  80723. return $this->noOutput;
  80724. }
  80725. /**
  80726. * @psalm-assert-if-true !null $this->noProgress
  80727. */
  80728. public function hasNoProgress(): bool
  80729. {
  80730. return $this->noProgress !== null;
  80731. }
  80732. /**
  80733. * @throws Exception
  80734. */
  80735. public function noProgress(): bool
  80736. {
  80737. if ($this->noProgress === null) {
  80738. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80739. }
  80740. return $this->noProgress;
  80741. }
  80742. /**
  80743. * @psalm-assert-if-true !null $this->noResults
  80744. */
  80745. public function hasNoResults(): bool
  80746. {
  80747. return $this->noResults !== null;
  80748. }
  80749. /**
  80750. * @throws Exception
  80751. */
  80752. public function noResults(): bool
  80753. {
  80754. if ($this->noResults === null) {
  80755. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80756. }
  80757. return $this->noResults;
  80758. }
  80759. /**
  80760. * @psalm-assert-if-true !null $this->noLogging
  80761. */
  80762. public function hasNoLogging(): bool
  80763. {
  80764. return $this->noLogging !== null;
  80765. }
  80766. /**
  80767. * @throws Exception
  80768. */
  80769. public function noLogging(): bool
  80770. {
  80771. if (!$this->hasNoLogging()) {
  80772. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80773. }
  80774. return $this->noLogging;
  80775. }
  80776. /**
  80777. * @psalm-assert-if-true !null $this->processIsolation
  80778. */
  80779. public function hasProcessIsolation(): bool
  80780. {
  80781. return $this->processIsolation !== null;
  80782. }
  80783. /**
  80784. * @throws Exception
  80785. */
  80786. public function processIsolation(): bool
  80787. {
  80788. if (!$this->hasProcessIsolation()) {
  80789. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80790. }
  80791. return $this->processIsolation;
  80792. }
  80793. /**
  80794. * @psalm-assert-if-true !null $this->randomOrderSeed
  80795. */
  80796. public function hasRandomOrderSeed(): bool
  80797. {
  80798. return $this->randomOrderSeed !== null;
  80799. }
  80800. /**
  80801. * @throws Exception
  80802. */
  80803. public function randomOrderSeed(): int
  80804. {
  80805. if (!$this->hasRandomOrderSeed()) {
  80806. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80807. }
  80808. return $this->randomOrderSeed;
  80809. }
  80810. /**
  80811. * @psalm-assert-if-true !null $this->reportUselessTests
  80812. */
  80813. public function hasReportUselessTests(): bool
  80814. {
  80815. return $this->reportUselessTests !== null;
  80816. }
  80817. /**
  80818. * @throws Exception
  80819. */
  80820. public function reportUselessTests(): bool
  80821. {
  80822. if (!$this->hasReportUselessTests()) {
  80823. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80824. }
  80825. return $this->reportUselessTests;
  80826. }
  80827. /**
  80828. * @psalm-assert-if-true !null $this->resolveDependencies
  80829. */
  80830. public function hasResolveDependencies(): bool
  80831. {
  80832. return $this->resolveDependencies !== null;
  80833. }
  80834. /**
  80835. * @throws Exception
  80836. */
  80837. public function resolveDependencies(): bool
  80838. {
  80839. if (!$this->hasResolveDependencies()) {
  80840. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80841. }
  80842. return $this->resolveDependencies;
  80843. }
  80844. /**
  80845. * @psalm-assert-if-true !null $this->reverseList
  80846. */
  80847. public function hasReverseList(): bool
  80848. {
  80849. return $this->reverseList !== null;
  80850. }
  80851. /**
  80852. * @throws Exception
  80853. */
  80854. public function reverseList(): bool
  80855. {
  80856. if (!$this->hasReverseList()) {
  80857. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80858. }
  80859. return $this->reverseList;
  80860. }
  80861. /**
  80862. * @psalm-assert-if-true !null $this->stderr
  80863. */
  80864. public function hasStderr(): bool
  80865. {
  80866. return $this->stderr !== null;
  80867. }
  80868. /**
  80869. * @throws Exception
  80870. */
  80871. public function stderr(): bool
  80872. {
  80873. if (!$this->hasStderr()) {
  80874. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80875. }
  80876. return $this->stderr;
  80877. }
  80878. /**
  80879. * @psalm-assert-if-true !null $this->strictCoverage
  80880. */
  80881. public function hasStrictCoverage(): bool
  80882. {
  80883. return $this->strictCoverage !== null;
  80884. }
  80885. /**
  80886. * @throws Exception
  80887. */
  80888. public function strictCoverage(): bool
  80889. {
  80890. if (!$this->hasStrictCoverage()) {
  80891. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80892. }
  80893. return $this->strictCoverage;
  80894. }
  80895. /**
  80896. * @psalm-assert-if-true !null $this->teamcityLogfile
  80897. */
  80898. public function hasTeamcityLogfile(): bool
  80899. {
  80900. return $this->teamcityLogfile !== null;
  80901. }
  80902. /**
  80903. * @throws Exception
  80904. */
  80905. public function teamcityLogfile(): string
  80906. {
  80907. if (!$this->hasTeamcityLogfile()) {
  80908. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80909. }
  80910. return $this->teamcityLogfile;
  80911. }
  80912. /**
  80913. * @psalm-assert-if-true !null $this->teamcityPrinter
  80914. */
  80915. public function hasTeamCityPrinter(): bool
  80916. {
  80917. return $this->teamCityPrinter !== null;
  80918. }
  80919. /**
  80920. * @throws Exception
  80921. */
  80922. public function teamCityPrinter(): bool
  80923. {
  80924. if (!$this->hasTeamCityPrinter()) {
  80925. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80926. }
  80927. return $this->teamCityPrinter;
  80928. }
  80929. /**
  80930. * @psalm-assert-if-true !null $this->testdoxHtmlFile
  80931. */
  80932. public function hasTestdoxHtmlFile(): bool
  80933. {
  80934. return $this->testdoxHtmlFile !== null;
  80935. }
  80936. /**
  80937. * @throws Exception
  80938. */
  80939. public function testdoxHtmlFile(): string
  80940. {
  80941. if (!$this->hasTestdoxHtmlFile()) {
  80942. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80943. }
  80944. return $this->testdoxHtmlFile;
  80945. }
  80946. /**
  80947. * @psalm-assert-if-true !null $this->testdoxTextFile
  80948. */
  80949. public function hasTestdoxTextFile(): bool
  80950. {
  80951. return $this->testdoxTextFile !== null;
  80952. }
  80953. /**
  80954. * @throws Exception
  80955. */
  80956. public function testdoxTextFile(): string
  80957. {
  80958. if (!$this->hasTestdoxTextFile()) {
  80959. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80960. }
  80961. return $this->testdoxTextFile;
  80962. }
  80963. /**
  80964. * @psalm-assert-if-true !null $this->testdoxPrinter
  80965. */
  80966. public function hasTestDoxPrinter(): bool
  80967. {
  80968. return $this->testdoxPrinter !== null;
  80969. }
  80970. /**
  80971. * @throws Exception
  80972. */
  80973. public function testdoxPrinter(): bool
  80974. {
  80975. if (!$this->hasTestdoxPrinter()) {
  80976. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80977. }
  80978. return $this->testdoxPrinter;
  80979. }
  80980. /**
  80981. * @psalm-assert-if-true !null $this->testSuffixes
  80982. */
  80983. public function hasTestSuffixes(): bool
  80984. {
  80985. return $this->testSuffixes !== null;
  80986. }
  80987. /**
  80988. * @psalm-return non-empty-list<non-empty-string>
  80989. *
  80990. * @throws Exception
  80991. */
  80992. public function testSuffixes(): array
  80993. {
  80994. if (!$this->hasTestSuffixes()) {
  80995. throw new \PHPUnit\TextUI\CliArguments\Exception();
  80996. }
  80997. return $this->testSuffixes;
  80998. }
  80999. /**
  81000. * @psalm-assert-if-true !null $this->testSuite
  81001. */
  81002. public function hasTestSuite(): bool
  81003. {
  81004. return $this->testSuite !== null;
  81005. }
  81006. /**
  81007. * @throws Exception
  81008. */
  81009. public function testSuite(): string
  81010. {
  81011. if (!$this->hasTestSuite()) {
  81012. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81013. }
  81014. return $this->testSuite;
  81015. }
  81016. /**
  81017. * @psalm-assert-if-true !null $this->excludedTestSuite
  81018. */
  81019. public function hasExcludedTestSuite(): bool
  81020. {
  81021. return $this->excludeTestSuite !== null;
  81022. }
  81023. /**
  81024. * @throws Exception
  81025. */
  81026. public function excludedTestSuite(): string
  81027. {
  81028. if (!$this->hasExcludedTestSuite()) {
  81029. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81030. }
  81031. return $this->excludeTestSuite;
  81032. }
  81033. public function useDefaultConfiguration(): bool
  81034. {
  81035. return $this->useDefaultConfiguration;
  81036. }
  81037. /**
  81038. * @psalm-assert-if-true !null $this->displayDetailsOnIncompleteTests
  81039. */
  81040. public function hasDisplayDetailsOnIncompleteTests(): bool
  81041. {
  81042. return $this->displayDetailsOnIncompleteTests !== null;
  81043. }
  81044. /**
  81045. * @throws Exception
  81046. */
  81047. public function displayDetailsOnIncompleteTests(): bool
  81048. {
  81049. if (!$this->hasDisplayDetailsOnIncompleteTests()) {
  81050. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81051. }
  81052. return $this->displayDetailsOnIncompleteTests;
  81053. }
  81054. /**
  81055. * @psalm-assert-if-true !null $this->displayDetailsOnSkippedTests
  81056. */
  81057. public function hasDisplayDetailsOnSkippedTests(): bool
  81058. {
  81059. return $this->displayDetailsOnSkippedTests !== null;
  81060. }
  81061. /**
  81062. * @throws Exception
  81063. */
  81064. public function displayDetailsOnSkippedTests(): bool
  81065. {
  81066. if (!$this->hasDisplayDetailsOnSkippedTests()) {
  81067. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81068. }
  81069. return $this->displayDetailsOnSkippedTests;
  81070. }
  81071. /**
  81072. * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerDeprecations
  81073. */
  81074. public function hasDisplayDetailsOnTestsThatTriggerDeprecations(): bool
  81075. {
  81076. return $this->displayDetailsOnTestsThatTriggerDeprecations !== null;
  81077. }
  81078. /**
  81079. * @throws Exception
  81080. */
  81081. public function displayDetailsOnTestsThatTriggerDeprecations(): bool
  81082. {
  81083. if (!$this->hasDisplayDetailsOnTestsThatTriggerDeprecations()) {
  81084. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81085. }
  81086. return $this->displayDetailsOnTestsThatTriggerDeprecations;
  81087. }
  81088. /**
  81089. * @psalm-assert-if-true !null $this->displayDetailsOnPhpunitDeprecations
  81090. */
  81091. public function hasDisplayDetailsOnPhpunitDeprecations(): bool
  81092. {
  81093. return $this->displayDetailsOnPhpunitDeprecations !== null;
  81094. }
  81095. /**
  81096. * @throws Exception
  81097. */
  81098. public function displayDetailsOnPhpunitDeprecations(): bool
  81099. {
  81100. if (!$this->hasDisplayDetailsOnPhpunitDeprecations()) {
  81101. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81102. }
  81103. return $this->displayDetailsOnPhpunitDeprecations;
  81104. }
  81105. /**
  81106. * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerErrors
  81107. */
  81108. public function hasDisplayDetailsOnTestsThatTriggerErrors(): bool
  81109. {
  81110. return $this->displayDetailsOnTestsThatTriggerErrors !== null;
  81111. }
  81112. /**
  81113. * @throws Exception
  81114. */
  81115. public function displayDetailsOnTestsThatTriggerErrors(): bool
  81116. {
  81117. if (!$this->hasDisplayDetailsOnTestsThatTriggerErrors()) {
  81118. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81119. }
  81120. return $this->displayDetailsOnTestsThatTriggerErrors;
  81121. }
  81122. /**
  81123. * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerNotices
  81124. */
  81125. public function hasDisplayDetailsOnTestsThatTriggerNotices(): bool
  81126. {
  81127. return $this->displayDetailsOnTestsThatTriggerNotices !== null;
  81128. }
  81129. /**
  81130. * @throws Exception
  81131. */
  81132. public function displayDetailsOnTestsThatTriggerNotices(): bool
  81133. {
  81134. if (!$this->hasDisplayDetailsOnTestsThatTriggerNotices()) {
  81135. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81136. }
  81137. return $this->displayDetailsOnTestsThatTriggerNotices;
  81138. }
  81139. /**
  81140. * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerWarnings
  81141. */
  81142. public function hasDisplayDetailsOnTestsThatTriggerWarnings(): bool
  81143. {
  81144. return $this->displayDetailsOnTestsThatTriggerWarnings !== null;
  81145. }
  81146. /**
  81147. * @throws Exception
  81148. */
  81149. public function displayDetailsOnTestsThatTriggerWarnings(): bool
  81150. {
  81151. if (!$this->hasDisplayDetailsOnTestsThatTriggerWarnings()) {
  81152. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81153. }
  81154. return $this->displayDetailsOnTestsThatTriggerWarnings;
  81155. }
  81156. public function version(): bool
  81157. {
  81158. return $this->version;
  81159. }
  81160. /**
  81161. * @psalm-assert-if-true !null $this->logEventsText
  81162. */
  81163. public function hasLogEventsText(): bool
  81164. {
  81165. return $this->logEventsText !== null;
  81166. }
  81167. /**
  81168. * @throws Exception
  81169. */
  81170. public function logEventsText(): string
  81171. {
  81172. if (!$this->hasLogEventsText()) {
  81173. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81174. }
  81175. return $this->logEventsText;
  81176. }
  81177. /**
  81178. * @psalm-assert-if-true !null $this->logEventsVerboseText
  81179. */
  81180. public function hasLogEventsVerboseText(): bool
  81181. {
  81182. return $this->logEventsVerboseText !== null;
  81183. }
  81184. /**
  81185. * @throws Exception
  81186. */
  81187. public function logEventsVerboseText(): string
  81188. {
  81189. if (!$this->hasLogEventsVerboseText()) {
  81190. throw new \PHPUnit\TextUI\CliArguments\Exception();
  81191. }
  81192. return $this->logEventsVerboseText;
  81193. }
  81194. public function debug(): bool
  81195. {
  81196. return $this->debug;
  81197. }
  81198. }
  81199. <?php
  81200. declare (strict_types=1);
  81201. /*
  81202. * This file is part of PHPUnit.
  81203. *
  81204. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  81205. *
  81206. * For the full copyright and license information, please view the LICENSE
  81207. * file that was distributed with this source code.
  81208. */
  81209. namespace PHPUnit\TextUI\CliArguments;
  81210. use RuntimeException;
  81211. /**
  81212. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  81213. *
  81214. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  81215. */
  81216. final class Exception extends RuntimeException implements \PHPUnit\Exception
  81217. {
  81218. }
  81219. <?php
  81220. declare (strict_types=1);
  81221. /*
  81222. * This file is part of PHPUnit.
  81223. *
  81224. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  81225. *
  81226. * For the full copyright and license information, please view the LICENSE
  81227. * file that was distributed with this source code.
  81228. */
  81229. namespace PHPUnit\TextUI\CliArguments;
  81230. use function getcwd;
  81231. use function is_dir;
  81232. use function is_file;
  81233. use function realpath;
  81234. /**
  81235. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  81236. *
  81237. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  81238. */
  81239. final class XmlConfigurationFileFinder
  81240. {
  81241. public function find(\PHPUnit\TextUI\CliArguments\Configuration $configuration): false|string
  81242. {
  81243. $useDefaultConfiguration = $configuration->useDefaultConfiguration();
  81244. if ($configuration->hasConfigurationFile()) {
  81245. if (is_dir($configuration->configurationFile())) {
  81246. $candidate = $this->configurationFileInDirectory($configuration->configurationFile());
  81247. if ($candidate !== \false) {
  81248. return $candidate;
  81249. }
  81250. return \false;
  81251. }
  81252. return $configuration->configurationFile();
  81253. }
  81254. if ($useDefaultConfiguration) {
  81255. $candidate = $this->configurationFileInDirectory(getcwd());
  81256. if ($candidate !== \false) {
  81257. return $candidate;
  81258. }
  81259. }
  81260. return \false;
  81261. }
  81262. private function configurationFileInDirectory(string $directory): false|string
  81263. {
  81264. $candidates = [$directory . '/phpunit.xml', $directory . '/phpunit.dist.xml', $directory . '/phpunit.xml.dist'];
  81265. foreach ($candidates as $candidate) {
  81266. if (is_file($candidate)) {
  81267. return realpath($candidate);
  81268. }
  81269. }
  81270. return \false;
  81271. }
  81272. }
  81273. <?php
  81274. declare (strict_types=1);
  81275. /*
  81276. * This file is part of PHPUnit.
  81277. *
  81278. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  81279. *
  81280. * For the full copyright and license information, please view the LICENSE
  81281. * file that was distributed with this source code.
  81282. */
  81283. namespace PHPUnit\TextUI\Configuration;
  81284. use function array_keys;
  81285. use function assert;
  81286. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  81287. /**
  81288. * CLI options and XML configuration are static within a single PHPUnit process.
  81289. * It is therefore okay to use a Singleton registry here.
  81290. *
  81291. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  81292. *
  81293. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  81294. */
  81295. final class CodeCoverageFilterRegistry
  81296. {
  81297. private static ?self $instance = null;
  81298. private ?Filter $filter = null;
  81299. private bool $configured = \false;
  81300. public static function instance(): self
  81301. {
  81302. if (self::$instance === null) {
  81303. self::$instance = new self();
  81304. }
  81305. return self::$instance;
  81306. }
  81307. /**
  81308. * @codeCoverageIgnore
  81309. */
  81310. public function get(): Filter
  81311. {
  81312. assert($this->filter !== null);
  81313. return $this->filter;
  81314. }
  81315. /**
  81316. * @codeCoverageIgnore
  81317. */
  81318. public function init(\PHPUnit\TextUI\Configuration\Configuration $configuration, bool $force = \false): void
  81319. {
  81320. if (!$configuration->hasCoverageReport() && !$force) {
  81321. return;
  81322. }
  81323. if ($this->configured && !$force) {
  81324. return;
  81325. }
  81326. $this->filter = new Filter();
  81327. if ($configuration->source()->notEmpty()) {
  81328. $this->filter->includeFiles(array_keys((new \PHPUnit\TextUI\Configuration\SourceMapper())->map($configuration->source())));
  81329. $this->configured = \true;
  81330. }
  81331. }
  81332. /**
  81333. * @codeCoverageIgnore
  81334. */
  81335. public function configured(): bool
  81336. {
  81337. return $this->configured;
  81338. }
  81339. }
  81340. <?php
  81341. declare (strict_types=1);
  81342. /*
  81343. * This file is part of PHPUnit.
  81344. *
  81345. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  81346. *
  81347. * For the full copyright and license information, please view the LICENSE
  81348. * file that was distributed with this source code.
  81349. */
  81350. namespace PHPUnit\TextUI\Configuration;
  81351. /**
  81352. * @psalm-immutable
  81353. *
  81354. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  81355. */
  81356. final class Configuration
  81357. {
  81358. public const COLOR_NEVER = 'never';
  81359. public const COLOR_AUTO = 'auto';
  81360. public const COLOR_ALWAYS = 'always';
  81361. public const COLOR_DEFAULT = self::COLOR_NEVER;
  81362. /**
  81363. * @psalm-var list<non-empty-string>
  81364. */
  81365. private readonly array $cliArguments;
  81366. private readonly ?string $configurationFile;
  81367. private readonly ?string $bootstrap;
  81368. private readonly bool $cacheResult;
  81369. private readonly ?string $cacheDirectory;
  81370. private readonly ?string $coverageCacheDirectory;
  81371. private readonly \PHPUnit\TextUI\Configuration\Source $source;
  81372. private readonly bool $pathCoverage;
  81373. private readonly ?string $coverageClover;
  81374. private readonly ?string $coverageCobertura;
  81375. private readonly ?string $coverageCrap4j;
  81376. private readonly int $coverageCrap4jThreshold;
  81377. private readonly ?string $coverageHtml;
  81378. private readonly int $coverageHtmlLowUpperBound;
  81379. private readonly int $coverageHtmlHighLowerBound;
  81380. private readonly string $coverageHtmlColorSuccessLow;
  81381. private readonly string $coverageHtmlColorSuccessMedium;
  81382. private readonly string $coverageHtmlColorSuccessHigh;
  81383. private readonly string $coverageHtmlColorWarning;
  81384. private readonly string $coverageHtmlColorDanger;
  81385. private readonly ?string $coverageHtmlCustomCssFile;
  81386. private readonly ?string $coveragePhp;
  81387. private readonly ?string $coverageText;
  81388. private readonly bool $coverageTextShowUncoveredFiles;
  81389. private readonly bool $coverageTextShowOnlySummary;
  81390. private readonly ?string $coverageXml;
  81391. private readonly string $testResultCacheFile;
  81392. private readonly bool $ignoreDeprecatedCodeUnitsFromCodeCoverage;
  81393. private readonly bool $disableCodeCoverageIgnore;
  81394. private readonly bool $failOnDeprecation;
  81395. private readonly bool $failOnPhpunitDeprecation;
  81396. private readonly bool $failOnEmptyTestSuite;
  81397. private readonly bool $failOnIncomplete;
  81398. private readonly bool $failOnNotice;
  81399. private readonly bool $failOnRisky;
  81400. private readonly bool $failOnSkipped;
  81401. private readonly bool $failOnWarning;
  81402. private readonly bool $stopOnDefect;
  81403. private readonly bool $stopOnDeprecation;
  81404. private readonly bool $stopOnError;
  81405. private readonly bool $stopOnFailure;
  81406. private readonly bool $stopOnIncomplete;
  81407. private readonly bool $stopOnNotice;
  81408. private readonly bool $stopOnRisky;
  81409. private readonly bool $stopOnSkipped;
  81410. private readonly bool $stopOnWarning;
  81411. private readonly bool $outputToStandardErrorStream;
  81412. private readonly int $columns;
  81413. private readonly bool $noExtensions;
  81414. /**
  81415. * @psalm-var ?non-empty-string
  81416. */
  81417. private readonly ?string $pharExtensionDirectory;
  81418. /**
  81419. * @psalm-var list<array{className: class-string, parameters: array<string, string>}>
  81420. */
  81421. private readonly array $extensionBootstrappers;
  81422. private readonly bool $backupGlobals;
  81423. private readonly bool $backupStaticProperties;
  81424. private readonly bool $beStrictAboutChangesToGlobalState;
  81425. private readonly bool $colors;
  81426. private readonly bool $processIsolation;
  81427. private readonly bool $enforceTimeLimit;
  81428. private readonly int $defaultTimeLimit;
  81429. private readonly int $timeoutForSmallTests;
  81430. private readonly int $timeoutForMediumTests;
  81431. private readonly int $timeoutForLargeTests;
  81432. private readonly bool $reportUselessTests;
  81433. private readonly bool $strictCoverage;
  81434. private readonly bool $disallowTestOutput;
  81435. private readonly bool $displayDetailsOnIncompleteTests;
  81436. private readonly bool $displayDetailsOnSkippedTests;
  81437. private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
  81438. private readonly bool $displayDetailsOnPhpunitDeprecations;
  81439. private readonly bool $displayDetailsOnTestsThatTriggerErrors;
  81440. private readonly bool $displayDetailsOnTestsThatTriggerNotices;
  81441. private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
  81442. private readonly bool $reverseDefectList;
  81443. private readonly bool $requireCoverageMetadata;
  81444. private readonly bool $registerMockObjectsFromTestArgumentsRecursively;
  81445. private readonly bool $noProgress;
  81446. private readonly bool $noResults;
  81447. private readonly bool $noOutput;
  81448. private readonly int $executionOrder;
  81449. private readonly int $executionOrderDefects;
  81450. private readonly bool $resolveDependencies;
  81451. private readonly ?string $logfileTeamcity;
  81452. private readonly ?string $logfileJunit;
  81453. private readonly ?string $logfileTestdoxHtml;
  81454. private readonly ?string $logfileTestdoxText;
  81455. private readonly ?string $logEventsText;
  81456. private readonly ?string $logEventsVerboseText;
  81457. private readonly ?array $testsCovering;
  81458. private readonly ?array $testsUsing;
  81459. private readonly bool $teamCityOutput;
  81460. private readonly bool $testDoxOutput;
  81461. private readonly ?string $filter;
  81462. private readonly ?array $groups;
  81463. private readonly ?array $excludeGroups;
  81464. private readonly int $randomOrderSeed;
  81465. private readonly bool $includeUncoveredFiles;
  81466. private readonly \PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuite;
  81467. private readonly string $includeTestSuite;
  81468. private readonly string $excludeTestSuite;
  81469. private readonly ?string $defaultTestSuite;
  81470. /**
  81471. * @psalm-var non-empty-list<non-empty-string>
  81472. */
  81473. private readonly array $testSuffixes;
  81474. private readonly \PHPUnit\TextUI\Configuration\Php $php;
  81475. private readonly bool $controlGarbageCollector;
  81476. private readonly int $numberOfTestsBeforeGarbageCollection;
  81477. private readonly ?string $generateBaseline;
  81478. private readonly bool $debug;
  81479. /**
  81480. * @psalm-param list<non-empty-string> $cliArguments
  81481. * @psalm-param ?non-empty-string $pharExtensionDirectory
  81482. * @psalm-param non-empty-list<non-empty-string> $testSuffixes
  81483. * @psalm-param list<array{className: class-string, parameters: array<string, string>}> $extensionBootstrappers
  81484. */
  81485. public function __construct(array $cliArguments, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, \PHPUnit\TextUI\Configuration\Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, int $randomOrderSeed, bool $includeUncoveredFiles, \PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, \PHPUnit\TextUI\Configuration\Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug)
  81486. {
  81487. $this->cliArguments = $cliArguments;
  81488. $this->configurationFile = $configurationFile;
  81489. $this->bootstrap = $bootstrap;
  81490. $this->cacheResult = $cacheResult;
  81491. $this->cacheDirectory = $cacheDirectory;
  81492. $this->coverageCacheDirectory = $coverageCacheDirectory;
  81493. $this->source = $source;
  81494. $this->testResultCacheFile = $testResultCacheFile;
  81495. $this->coverageClover = $coverageClover;
  81496. $this->coverageCobertura = $coverageCobertura;
  81497. $this->coverageCrap4j = $coverageCrap4j;
  81498. $this->coverageCrap4jThreshold = $coverageCrap4jThreshold;
  81499. $this->coverageHtml = $coverageHtml;
  81500. $this->coverageHtmlLowUpperBound = $coverageHtmlLowUpperBound;
  81501. $this->coverageHtmlHighLowerBound = $coverageHtmlHighLowerBound;
  81502. $this->coverageHtmlColorSuccessLow = $coverageHtmlColorSuccessLow;
  81503. $this->coverageHtmlColorSuccessMedium = $coverageHtmlColorSuccessMedium;
  81504. $this->coverageHtmlColorSuccessHigh = $coverageHtmlColorSuccessHigh;
  81505. $this->coverageHtmlColorWarning = $coverageHtmlColorWarning;
  81506. $this->coverageHtmlColorDanger = $coverageHtmlColorDanger;
  81507. $this->coverageHtmlCustomCssFile = $coverageHtmlCustomCssFile;
  81508. $this->coveragePhp = $coveragePhp;
  81509. $this->coverageText = $coverageText;
  81510. $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles;
  81511. $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary;
  81512. $this->coverageXml = $coverageXml;
  81513. $this->pathCoverage = $pathCoverage;
  81514. $this->ignoreDeprecatedCodeUnitsFromCodeCoverage = $ignoreDeprecatedCodeUnitsFromCodeCoverage;
  81515. $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
  81516. $this->failOnDeprecation = $failOnDeprecation;
  81517. $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
  81518. $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
  81519. $this->failOnIncomplete = $failOnIncomplete;
  81520. $this->failOnNotice = $failOnNotice;
  81521. $this->failOnRisky = $failOnRisky;
  81522. $this->failOnSkipped = $failOnSkipped;
  81523. $this->failOnWarning = $failOnWarning;
  81524. $this->stopOnDefect = $stopOnDefect;
  81525. $this->stopOnDeprecation = $stopOnDeprecation;
  81526. $this->stopOnError = $stopOnError;
  81527. $this->stopOnFailure = $stopOnFailure;
  81528. $this->stopOnIncomplete = $stopOnIncomplete;
  81529. $this->stopOnNotice = $stopOnNotice;
  81530. $this->stopOnRisky = $stopOnRisky;
  81531. $this->stopOnSkipped = $stopOnSkipped;
  81532. $this->stopOnWarning = $stopOnWarning;
  81533. $this->outputToStandardErrorStream = $outputToStandardErrorStream;
  81534. $this->columns = $columns;
  81535. $this->noExtensions = $noExtensions;
  81536. $this->pharExtensionDirectory = $pharExtensionDirectory;
  81537. $this->extensionBootstrappers = $extensionBootstrappers;
  81538. $this->backupGlobals = $backupGlobals;
  81539. $this->backupStaticProperties = $backupStaticProperties;
  81540. $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
  81541. $this->colors = $colors;
  81542. $this->processIsolation = $processIsolation;
  81543. $this->enforceTimeLimit = $enforceTimeLimit;
  81544. $this->defaultTimeLimit = $defaultTimeLimit;
  81545. $this->timeoutForSmallTests = $timeoutForSmallTests;
  81546. $this->timeoutForMediumTests = $timeoutForMediumTests;
  81547. $this->timeoutForLargeTests = $timeoutForLargeTests;
  81548. $this->reportUselessTests = $reportUselessTests;
  81549. $this->strictCoverage = $strictCoverage;
  81550. $this->disallowTestOutput = $disallowTestOutput;
  81551. $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
  81552. $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
  81553. $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
  81554. $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
  81555. $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
  81556. $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
  81557. $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
  81558. $this->reverseDefectList = $reverseDefectList;
  81559. $this->requireCoverageMetadata = $requireCoverageMetadata;
  81560. $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively;
  81561. $this->noProgress = $noProgress;
  81562. $this->noResults = $noResults;
  81563. $this->noOutput = $noOutput;
  81564. $this->executionOrder = $executionOrder;
  81565. $this->executionOrderDefects = $executionOrderDefects;
  81566. $this->resolveDependencies = $resolveDependencies;
  81567. $this->logfileTeamcity = $logfileTeamcity;
  81568. $this->logfileJunit = $logfileJunit;
  81569. $this->logfileTestdoxHtml = $logfileTestdoxHtml;
  81570. $this->logfileTestdoxText = $logfileTestdoxText;
  81571. $this->logEventsText = $logEventsText;
  81572. $this->logEventsVerboseText = $logEventsVerboseText;
  81573. $this->teamCityOutput = $teamCityOutput;
  81574. $this->testDoxOutput = $testDoxOutput;
  81575. $this->testsCovering = $testsCovering;
  81576. $this->testsUsing = $testsUsing;
  81577. $this->filter = $filter;
  81578. $this->groups = $groups;
  81579. $this->excludeGroups = $excludeGroups;
  81580. $this->randomOrderSeed = $randomOrderSeed;
  81581. $this->includeUncoveredFiles = $includeUncoveredFiles;
  81582. $this->testSuite = $testSuite;
  81583. $this->includeTestSuite = $includeTestSuite;
  81584. $this->excludeTestSuite = $excludeTestSuite;
  81585. $this->defaultTestSuite = $defaultTestSuite;
  81586. $this->testSuffixes = $testSuffixes;
  81587. $this->php = $php;
  81588. $this->controlGarbageCollector = $controlGarbageCollector;
  81589. $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection;
  81590. $this->generateBaseline = $generateBaseline;
  81591. $this->debug = $debug;
  81592. }
  81593. /**
  81594. * @psalm-assert-if-true !empty $this->cliArguments
  81595. */
  81596. public function hasCliArguments(): bool
  81597. {
  81598. return !empty($this->cliArguments);
  81599. }
  81600. /**
  81601. * @psalm-return list<non-empty-string>
  81602. */
  81603. public function cliArguments(): array
  81604. {
  81605. return $this->cliArguments;
  81606. }
  81607. /**
  81608. * @psalm-assert-if-true !empty $this->cliArguments
  81609. *
  81610. * @deprecated Use hasCliArguments() instead
  81611. */
  81612. public function hasCliArgument(): bool
  81613. {
  81614. return !empty($this->cliArguments);
  81615. }
  81616. /**
  81617. * @throws NoCliArgumentException
  81618. *
  81619. * @return non-empty-string
  81620. *
  81621. * @deprecated Use cliArguments()[0] instead
  81622. */
  81623. public function cliArgument(): string
  81624. {
  81625. if (!$this->hasCliArguments()) {
  81626. throw new \PHPUnit\TextUI\Configuration\NoCliArgumentException();
  81627. }
  81628. return $this->cliArguments[0];
  81629. }
  81630. /**
  81631. * @psalm-assert-if-true !null $this->configurationFile
  81632. */
  81633. public function hasConfigurationFile(): bool
  81634. {
  81635. return $this->configurationFile !== null;
  81636. }
  81637. /**
  81638. * @throws NoConfigurationFileException
  81639. */
  81640. public function configurationFile(): string
  81641. {
  81642. if (!$this->hasConfigurationFile()) {
  81643. throw new \PHPUnit\TextUI\Configuration\NoConfigurationFileException();
  81644. }
  81645. return $this->configurationFile;
  81646. }
  81647. /**
  81648. * @psalm-assert-if-true !null $this->bootstrap
  81649. */
  81650. public function hasBootstrap(): bool
  81651. {
  81652. return $this->bootstrap !== null;
  81653. }
  81654. /**
  81655. * @throws NoBootstrapException
  81656. */
  81657. public function bootstrap(): string
  81658. {
  81659. if (!$this->hasBootstrap()) {
  81660. throw new \PHPUnit\TextUI\Configuration\NoBootstrapException();
  81661. }
  81662. return $this->bootstrap;
  81663. }
  81664. public function cacheResult(): bool
  81665. {
  81666. return $this->cacheResult;
  81667. }
  81668. /**
  81669. * @psalm-assert-if-true !null $this->cacheDirectory
  81670. */
  81671. public function hasCacheDirectory(): bool
  81672. {
  81673. return $this->cacheDirectory !== null;
  81674. }
  81675. /**
  81676. * @throws NoCacheDirectoryException
  81677. */
  81678. public function cacheDirectory(): string
  81679. {
  81680. if (!$this->hasCacheDirectory()) {
  81681. throw new \PHPUnit\TextUI\Configuration\NoCacheDirectoryException();
  81682. }
  81683. return $this->cacheDirectory;
  81684. }
  81685. /**
  81686. * @psalm-assert-if-true !null $this->coverageCacheDirectory
  81687. */
  81688. public function hasCoverageCacheDirectory(): bool
  81689. {
  81690. return $this->coverageCacheDirectory !== null;
  81691. }
  81692. /**
  81693. * @throws NoCoverageCacheDirectoryException
  81694. */
  81695. public function coverageCacheDirectory(): string
  81696. {
  81697. if (!$this->hasCoverageCacheDirectory()) {
  81698. throw new \PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException();
  81699. }
  81700. return $this->coverageCacheDirectory;
  81701. }
  81702. public function source(): \PHPUnit\TextUI\Configuration\Source
  81703. {
  81704. return $this->source;
  81705. }
  81706. /**
  81707. * @deprecated Use source()->restrictDeprecations() instead
  81708. */
  81709. public function restrictDeprecations(): bool
  81710. {
  81711. return $this->source()->restrictDeprecations();
  81712. }
  81713. /**
  81714. * @deprecated Use source()->restrictNotices() instead
  81715. */
  81716. public function restrictNotices(): bool
  81717. {
  81718. return $this->source()->restrictNotices();
  81719. }
  81720. /**
  81721. * @deprecated Use source()->restrictWarnings() instead
  81722. */
  81723. public function restrictWarnings(): bool
  81724. {
  81725. return $this->source()->restrictWarnings();
  81726. }
  81727. /**
  81728. * @deprecated Use source()->notEmpty() instead
  81729. */
  81730. public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool
  81731. {
  81732. return $this->source->notEmpty();
  81733. }
  81734. /**
  81735. * @deprecated Use source()->includeDirectories() instead
  81736. */
  81737. public function coverageIncludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
  81738. {
  81739. return $this->source()->includeDirectories();
  81740. }
  81741. /**
  81742. * @deprecated Use source()->includeFiles() instead
  81743. */
  81744. public function coverageIncludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
  81745. {
  81746. return $this->source()->includeFiles();
  81747. }
  81748. /**
  81749. * @deprecated Use source()->excludeDirectories() instead
  81750. */
  81751. public function coverageExcludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
  81752. {
  81753. return $this->source()->excludeDirectories();
  81754. }
  81755. /**
  81756. * @deprecated Use source()->excludeFiles() instead
  81757. */
  81758. public function coverageExcludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
  81759. {
  81760. return $this->source()->excludeFiles();
  81761. }
  81762. public function testResultCacheFile(): string
  81763. {
  81764. return $this->testResultCacheFile;
  81765. }
  81766. public function ignoreDeprecatedCodeUnitsFromCodeCoverage(): bool
  81767. {
  81768. return $this->ignoreDeprecatedCodeUnitsFromCodeCoverage;
  81769. }
  81770. public function disableCodeCoverageIgnore(): bool
  81771. {
  81772. return $this->disableCodeCoverageIgnore;
  81773. }
  81774. public function pathCoverage(): bool
  81775. {
  81776. return $this->pathCoverage;
  81777. }
  81778. public function hasCoverageReport(): bool
  81779. {
  81780. return $this->hasCoverageClover() || $this->hasCoverageCobertura() || $this->hasCoverageCrap4j() || $this->hasCoverageHtml() || $this->hasCoveragePhp() || $this->hasCoverageText() || $this->hasCoverageXml();
  81781. }
  81782. /**
  81783. * @psalm-assert-if-true !null $this->coverageClover
  81784. */
  81785. public function hasCoverageClover(): bool
  81786. {
  81787. return $this->coverageClover !== null;
  81788. }
  81789. /**
  81790. * @throws CodeCoverageReportNotConfiguredException
  81791. */
  81792. public function coverageClover(): string
  81793. {
  81794. if (!$this->hasCoverageClover()) {
  81795. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81796. }
  81797. return $this->coverageClover;
  81798. }
  81799. /**
  81800. * @psalm-assert-if-true !null $this->coverageCobertura
  81801. */
  81802. public function hasCoverageCobertura(): bool
  81803. {
  81804. return $this->coverageCobertura !== null;
  81805. }
  81806. /**
  81807. * @throws CodeCoverageReportNotConfiguredException
  81808. */
  81809. public function coverageCobertura(): string
  81810. {
  81811. if (!$this->hasCoverageCobertura()) {
  81812. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81813. }
  81814. return $this->coverageCobertura;
  81815. }
  81816. /**
  81817. * @psalm-assert-if-true !null $this->coverageCrap4j
  81818. */
  81819. public function hasCoverageCrap4j(): bool
  81820. {
  81821. return $this->coverageCrap4j !== null;
  81822. }
  81823. /**
  81824. * @throws CodeCoverageReportNotConfiguredException
  81825. */
  81826. public function coverageCrap4j(): string
  81827. {
  81828. if (!$this->hasCoverageCrap4j()) {
  81829. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81830. }
  81831. return $this->coverageCrap4j;
  81832. }
  81833. public function coverageCrap4jThreshold(): int
  81834. {
  81835. return $this->coverageCrap4jThreshold;
  81836. }
  81837. /**
  81838. * @psalm-assert-if-true !null $this->coverageHtml
  81839. */
  81840. public function hasCoverageHtml(): bool
  81841. {
  81842. return $this->coverageHtml !== null;
  81843. }
  81844. /**
  81845. * @throws CodeCoverageReportNotConfiguredException
  81846. */
  81847. public function coverageHtml(): string
  81848. {
  81849. if (!$this->hasCoverageHtml()) {
  81850. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81851. }
  81852. return $this->coverageHtml;
  81853. }
  81854. public function coverageHtmlLowUpperBound(): int
  81855. {
  81856. return $this->coverageHtmlLowUpperBound;
  81857. }
  81858. public function coverageHtmlHighLowerBound(): int
  81859. {
  81860. return $this->coverageHtmlHighLowerBound;
  81861. }
  81862. public function coverageHtmlColorSuccessLow(): string
  81863. {
  81864. return $this->coverageHtmlColorSuccessLow;
  81865. }
  81866. public function coverageHtmlColorSuccessMedium(): string
  81867. {
  81868. return $this->coverageHtmlColorSuccessMedium;
  81869. }
  81870. public function coverageHtmlColorSuccessHigh(): string
  81871. {
  81872. return $this->coverageHtmlColorSuccessHigh;
  81873. }
  81874. public function coverageHtmlColorWarning(): string
  81875. {
  81876. return $this->coverageHtmlColorWarning;
  81877. }
  81878. public function coverageHtmlColorDanger(): string
  81879. {
  81880. return $this->coverageHtmlColorDanger;
  81881. }
  81882. /**
  81883. * @psalm-assert-if-true !null $this->coverageHtmlCustomCssFile
  81884. */
  81885. public function hasCoverageHtmlCustomCssFile(): bool
  81886. {
  81887. return $this->coverageHtmlCustomCssFile !== null;
  81888. }
  81889. /**
  81890. * @throws NoCustomCssFileException
  81891. */
  81892. public function coverageHtmlCustomCssFile(): string
  81893. {
  81894. if (!$this->hasCoverageHtmlCustomCssFile()) {
  81895. throw new \PHPUnit\TextUI\Configuration\NoCustomCssFileException();
  81896. }
  81897. return $this->coverageHtmlCustomCssFile;
  81898. }
  81899. /**
  81900. * @psalm-assert-if-true !null $this->coveragePhp
  81901. */
  81902. public function hasCoveragePhp(): bool
  81903. {
  81904. return $this->coveragePhp !== null;
  81905. }
  81906. /**
  81907. * @throws CodeCoverageReportNotConfiguredException
  81908. */
  81909. public function coveragePhp(): string
  81910. {
  81911. if (!$this->hasCoveragePhp()) {
  81912. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81913. }
  81914. return $this->coveragePhp;
  81915. }
  81916. /**
  81917. * @psalm-assert-if-true !null $this->coverageText
  81918. */
  81919. public function hasCoverageText(): bool
  81920. {
  81921. return $this->coverageText !== null;
  81922. }
  81923. /**
  81924. * @throws CodeCoverageReportNotConfiguredException
  81925. */
  81926. public function coverageText(): string
  81927. {
  81928. if (!$this->hasCoverageText()) {
  81929. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81930. }
  81931. return $this->coverageText;
  81932. }
  81933. public function coverageTextShowUncoveredFiles(): bool
  81934. {
  81935. return $this->coverageTextShowUncoveredFiles;
  81936. }
  81937. public function coverageTextShowOnlySummary(): bool
  81938. {
  81939. return $this->coverageTextShowOnlySummary;
  81940. }
  81941. /**
  81942. * @psalm-assert-if-true !null $this->coverageXml
  81943. */
  81944. public function hasCoverageXml(): bool
  81945. {
  81946. return $this->coverageXml !== null;
  81947. }
  81948. /**
  81949. * @throws CodeCoverageReportNotConfiguredException
  81950. */
  81951. public function coverageXml(): string
  81952. {
  81953. if (!$this->hasCoverageXml()) {
  81954. throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
  81955. }
  81956. return $this->coverageXml;
  81957. }
  81958. public function failOnDeprecation(): bool
  81959. {
  81960. return $this->failOnDeprecation;
  81961. }
  81962. public function failOnPhpunitDeprecation(): bool
  81963. {
  81964. return $this->failOnPhpunitDeprecation;
  81965. }
  81966. public function failOnEmptyTestSuite(): bool
  81967. {
  81968. return $this->failOnEmptyTestSuite;
  81969. }
  81970. public function failOnIncomplete(): bool
  81971. {
  81972. return $this->failOnIncomplete;
  81973. }
  81974. public function failOnNotice(): bool
  81975. {
  81976. return $this->failOnNotice;
  81977. }
  81978. public function failOnRisky(): bool
  81979. {
  81980. return $this->failOnRisky;
  81981. }
  81982. public function failOnSkipped(): bool
  81983. {
  81984. return $this->failOnSkipped;
  81985. }
  81986. public function failOnWarning(): bool
  81987. {
  81988. return $this->failOnWarning;
  81989. }
  81990. public function stopOnDefect(): bool
  81991. {
  81992. return $this->stopOnDefect;
  81993. }
  81994. public function stopOnDeprecation(): bool
  81995. {
  81996. return $this->stopOnDeprecation;
  81997. }
  81998. public function stopOnError(): bool
  81999. {
  82000. return $this->stopOnError;
  82001. }
  82002. public function stopOnFailure(): bool
  82003. {
  82004. return $this->stopOnFailure;
  82005. }
  82006. public function stopOnIncomplete(): bool
  82007. {
  82008. return $this->stopOnIncomplete;
  82009. }
  82010. public function stopOnNotice(): bool
  82011. {
  82012. return $this->stopOnNotice;
  82013. }
  82014. public function stopOnRisky(): bool
  82015. {
  82016. return $this->stopOnRisky;
  82017. }
  82018. public function stopOnSkipped(): bool
  82019. {
  82020. return $this->stopOnSkipped;
  82021. }
  82022. public function stopOnWarning(): bool
  82023. {
  82024. return $this->stopOnWarning;
  82025. }
  82026. public function outputToStandardErrorStream(): bool
  82027. {
  82028. return $this->outputToStandardErrorStream;
  82029. }
  82030. public function columns(): int
  82031. {
  82032. return $this->columns;
  82033. }
  82034. /**
  82035. * @deprecated Use noExtensions() instead
  82036. */
  82037. public function loadPharExtensions(): bool
  82038. {
  82039. return $this->noExtensions;
  82040. }
  82041. public function noExtensions(): bool
  82042. {
  82043. return $this->noExtensions;
  82044. }
  82045. /**
  82046. * @psalm-assert-if-true !null $this->pharExtensionDirectory
  82047. */
  82048. public function hasPharExtensionDirectory(): bool
  82049. {
  82050. return $this->pharExtensionDirectory !== null;
  82051. }
  82052. /**
  82053. * @psalm-return non-empty-string
  82054. *
  82055. * @throws NoPharExtensionDirectoryException
  82056. */
  82057. public function pharExtensionDirectory(): string
  82058. {
  82059. if (!$this->hasPharExtensionDirectory()) {
  82060. throw new \PHPUnit\TextUI\Configuration\NoPharExtensionDirectoryException();
  82061. }
  82062. return $this->pharExtensionDirectory;
  82063. }
  82064. /**
  82065. * @psalm-return list<array{className: class-string, parameters: array<string, string>}>
  82066. */
  82067. public function extensionBootstrappers(): array
  82068. {
  82069. return $this->extensionBootstrappers;
  82070. }
  82071. public function backupGlobals(): bool
  82072. {
  82073. return $this->backupGlobals;
  82074. }
  82075. public function backupStaticProperties(): bool
  82076. {
  82077. return $this->backupStaticProperties;
  82078. }
  82079. public function beStrictAboutChangesToGlobalState(): bool
  82080. {
  82081. return $this->beStrictAboutChangesToGlobalState;
  82082. }
  82083. public function colors(): bool
  82084. {
  82085. return $this->colors;
  82086. }
  82087. public function processIsolation(): bool
  82088. {
  82089. return $this->processIsolation;
  82090. }
  82091. public function enforceTimeLimit(): bool
  82092. {
  82093. return $this->enforceTimeLimit;
  82094. }
  82095. public function defaultTimeLimit(): int
  82096. {
  82097. return $this->defaultTimeLimit;
  82098. }
  82099. public function timeoutForSmallTests(): int
  82100. {
  82101. return $this->timeoutForSmallTests;
  82102. }
  82103. public function timeoutForMediumTests(): int
  82104. {
  82105. return $this->timeoutForMediumTests;
  82106. }
  82107. public function timeoutForLargeTests(): int
  82108. {
  82109. return $this->timeoutForLargeTests;
  82110. }
  82111. public function reportUselessTests(): bool
  82112. {
  82113. return $this->reportUselessTests;
  82114. }
  82115. public function strictCoverage(): bool
  82116. {
  82117. return $this->strictCoverage;
  82118. }
  82119. public function disallowTestOutput(): bool
  82120. {
  82121. return $this->disallowTestOutput;
  82122. }
  82123. public function displayDetailsOnIncompleteTests(): bool
  82124. {
  82125. return $this->displayDetailsOnIncompleteTests;
  82126. }
  82127. public function displayDetailsOnSkippedTests(): bool
  82128. {
  82129. return $this->displayDetailsOnSkippedTests;
  82130. }
  82131. public function displayDetailsOnTestsThatTriggerDeprecations(): bool
  82132. {
  82133. return $this->displayDetailsOnTestsThatTriggerDeprecations;
  82134. }
  82135. public function displayDetailsOnPhpunitDeprecations(): bool
  82136. {
  82137. return $this->displayDetailsOnPhpunitDeprecations;
  82138. }
  82139. public function displayDetailsOnTestsThatTriggerErrors(): bool
  82140. {
  82141. return $this->displayDetailsOnTestsThatTriggerErrors;
  82142. }
  82143. public function displayDetailsOnTestsThatTriggerNotices(): bool
  82144. {
  82145. return $this->displayDetailsOnTestsThatTriggerNotices;
  82146. }
  82147. public function displayDetailsOnTestsThatTriggerWarnings(): bool
  82148. {
  82149. return $this->displayDetailsOnTestsThatTriggerWarnings;
  82150. }
  82151. public function reverseDefectList(): bool
  82152. {
  82153. return $this->reverseDefectList;
  82154. }
  82155. public function requireCoverageMetadata(): bool
  82156. {
  82157. return $this->requireCoverageMetadata;
  82158. }
  82159. /**
  82160. * @deprecated
  82161. */
  82162. public function registerMockObjectsFromTestArgumentsRecursively(): bool
  82163. {
  82164. return $this->registerMockObjectsFromTestArgumentsRecursively;
  82165. }
  82166. public function noProgress(): bool
  82167. {
  82168. return $this->noProgress;
  82169. }
  82170. public function noResults(): bool
  82171. {
  82172. return $this->noResults;
  82173. }
  82174. public function noOutput(): bool
  82175. {
  82176. return $this->noOutput;
  82177. }
  82178. public function executionOrder(): int
  82179. {
  82180. return $this->executionOrder;
  82181. }
  82182. public function executionOrderDefects(): int
  82183. {
  82184. return $this->executionOrderDefects;
  82185. }
  82186. public function resolveDependencies(): bool
  82187. {
  82188. return $this->resolveDependencies;
  82189. }
  82190. /**
  82191. * @psalm-assert-if-true !null $this->logfileTeamcity
  82192. */
  82193. public function hasLogfileTeamcity(): bool
  82194. {
  82195. return $this->logfileTeamcity !== null;
  82196. }
  82197. /**
  82198. * @throws LoggingNotConfiguredException
  82199. */
  82200. public function logfileTeamcity(): string
  82201. {
  82202. if (!$this->hasLogfileTeamcity()) {
  82203. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82204. }
  82205. return $this->logfileTeamcity;
  82206. }
  82207. /**
  82208. * @psalm-assert-if-true !null $this->logfileJunit
  82209. */
  82210. public function hasLogfileJunit(): bool
  82211. {
  82212. return $this->logfileJunit !== null;
  82213. }
  82214. /**
  82215. * @throws LoggingNotConfiguredException
  82216. */
  82217. public function logfileJunit(): string
  82218. {
  82219. if (!$this->hasLogfileJunit()) {
  82220. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82221. }
  82222. return $this->logfileJunit;
  82223. }
  82224. /**
  82225. * @psalm-assert-if-true !null $this->logfileTestdoxHtml
  82226. */
  82227. public function hasLogfileTestdoxHtml(): bool
  82228. {
  82229. return $this->logfileTestdoxHtml !== null;
  82230. }
  82231. /**
  82232. * @throws LoggingNotConfiguredException
  82233. */
  82234. public function logfileTestdoxHtml(): string
  82235. {
  82236. if (!$this->hasLogfileTestdoxHtml()) {
  82237. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82238. }
  82239. return $this->logfileTestdoxHtml;
  82240. }
  82241. /**
  82242. * @psalm-assert-if-true !null $this->logfileTestdoxText
  82243. */
  82244. public function hasLogfileTestdoxText(): bool
  82245. {
  82246. return $this->logfileTestdoxText !== null;
  82247. }
  82248. /**
  82249. * @throws LoggingNotConfiguredException
  82250. */
  82251. public function logfileTestdoxText(): string
  82252. {
  82253. if (!$this->hasLogfileTestdoxText()) {
  82254. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82255. }
  82256. return $this->logfileTestdoxText;
  82257. }
  82258. /**
  82259. * @psalm-assert-if-true !null $this->logEventsText
  82260. */
  82261. public function hasLogEventsText(): bool
  82262. {
  82263. return $this->logEventsText !== null;
  82264. }
  82265. /**
  82266. * @throws LoggingNotConfiguredException
  82267. */
  82268. public function logEventsText(): string
  82269. {
  82270. if (!$this->hasLogEventsText()) {
  82271. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82272. }
  82273. return $this->logEventsText;
  82274. }
  82275. /**
  82276. * @psalm-assert-if-true !null $this->logEventsVerboseText
  82277. */
  82278. public function hasLogEventsVerboseText(): bool
  82279. {
  82280. return $this->logEventsVerboseText !== null;
  82281. }
  82282. /**
  82283. * @throws LoggingNotConfiguredException
  82284. */
  82285. public function logEventsVerboseText(): string
  82286. {
  82287. if (!$this->hasLogEventsVerboseText()) {
  82288. throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
  82289. }
  82290. return $this->logEventsVerboseText;
  82291. }
  82292. public function outputIsTeamCity(): bool
  82293. {
  82294. return $this->teamCityOutput;
  82295. }
  82296. public function outputIsTestDox(): bool
  82297. {
  82298. return $this->testDoxOutput;
  82299. }
  82300. /**
  82301. * @psalm-assert-if-true !empty $this->testsCovering
  82302. */
  82303. public function hasTestsCovering(): bool
  82304. {
  82305. return !empty($this->testsCovering);
  82306. }
  82307. /**
  82308. * @psalm-return list<string>
  82309. *
  82310. * @throws FilterNotConfiguredException
  82311. */
  82312. public function testsCovering(): array
  82313. {
  82314. if (!$this->hasTestsCovering()) {
  82315. throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
  82316. }
  82317. return $this->testsCovering;
  82318. }
  82319. /**
  82320. * @psalm-assert-if-true !empty $this->testsUsing
  82321. */
  82322. public function hasTestsUsing(): bool
  82323. {
  82324. return !empty($this->testsUsing);
  82325. }
  82326. /**
  82327. * @psalm-return list<string>
  82328. *
  82329. * @throws FilterNotConfiguredException
  82330. */
  82331. public function testsUsing(): array
  82332. {
  82333. if (!$this->hasTestsUsing()) {
  82334. throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
  82335. }
  82336. return $this->testsUsing;
  82337. }
  82338. /**
  82339. * @psalm-assert-if-true !null $this->filter
  82340. */
  82341. public function hasFilter(): bool
  82342. {
  82343. return $this->filter !== null;
  82344. }
  82345. /**
  82346. * @throws FilterNotConfiguredException
  82347. */
  82348. public function filter(): string
  82349. {
  82350. if (!$this->hasFilter()) {
  82351. throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
  82352. }
  82353. return $this->filter;
  82354. }
  82355. /**
  82356. * @psalm-assert-if-true !empty $this->groups
  82357. */
  82358. public function hasGroups(): bool
  82359. {
  82360. return !empty($this->groups);
  82361. }
  82362. /**
  82363. * @throws FilterNotConfiguredException
  82364. */
  82365. public function groups(): array
  82366. {
  82367. if (!$this->hasGroups()) {
  82368. throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
  82369. }
  82370. return $this->groups;
  82371. }
  82372. /**
  82373. * @psalm-assert-if-true !empty $this->excludeGroups
  82374. */
  82375. public function hasExcludeGroups(): bool
  82376. {
  82377. return !empty($this->excludeGroups);
  82378. }
  82379. /**
  82380. * @throws FilterNotConfiguredException
  82381. */
  82382. public function excludeGroups(): array
  82383. {
  82384. if (!$this->hasExcludeGroups()) {
  82385. throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
  82386. }
  82387. return $this->excludeGroups;
  82388. }
  82389. public function randomOrderSeed(): int
  82390. {
  82391. return $this->randomOrderSeed;
  82392. }
  82393. public function includeUncoveredFiles(): bool
  82394. {
  82395. return $this->includeUncoveredFiles;
  82396. }
  82397. public function testSuite(): \PHPUnit\TextUI\Configuration\TestSuiteCollection
  82398. {
  82399. return $this->testSuite;
  82400. }
  82401. public function includeTestSuite(): string
  82402. {
  82403. return $this->includeTestSuite;
  82404. }
  82405. public function excludeTestSuite(): string
  82406. {
  82407. return $this->excludeTestSuite;
  82408. }
  82409. /**
  82410. * @psalm-assert-if-true !null $this->defaultTestSuite
  82411. */
  82412. public function hasDefaultTestSuite(): bool
  82413. {
  82414. return $this->defaultTestSuite !== null;
  82415. }
  82416. /**
  82417. * @throws NoDefaultTestSuiteException
  82418. */
  82419. public function defaultTestSuite(): string
  82420. {
  82421. if (!$this->hasDefaultTestSuite()) {
  82422. throw new \PHPUnit\TextUI\Configuration\NoDefaultTestSuiteException();
  82423. }
  82424. return $this->defaultTestSuite;
  82425. }
  82426. /**
  82427. * @psalm-return non-empty-list<non-empty-string>
  82428. */
  82429. public function testSuffixes(): array
  82430. {
  82431. return $this->testSuffixes;
  82432. }
  82433. public function php(): \PHPUnit\TextUI\Configuration\Php
  82434. {
  82435. return $this->php;
  82436. }
  82437. public function controlGarbageCollector(): bool
  82438. {
  82439. return $this->controlGarbageCollector;
  82440. }
  82441. public function numberOfTestsBeforeGarbageCollection(): int
  82442. {
  82443. return $this->numberOfTestsBeforeGarbageCollection;
  82444. }
  82445. /**
  82446. * @psalm-assert-if-true !null $this->generateBaseline
  82447. */
  82448. public function hasGenerateBaseline(): bool
  82449. {
  82450. return $this->generateBaseline !== null;
  82451. }
  82452. /**
  82453. * @throws NoBaselineException
  82454. */
  82455. public function generateBaseline(): string
  82456. {
  82457. if (!$this->hasGenerateBaseline()) {
  82458. throw new \PHPUnit\TextUI\Configuration\NoBaselineException();
  82459. }
  82460. return $this->generateBaseline;
  82461. }
  82462. public function debug(): bool
  82463. {
  82464. return $this->debug;
  82465. }
  82466. }
  82467. <?php
  82468. declare (strict_types=1);
  82469. /*
  82470. * This file is part of PHPUnit.
  82471. *
  82472. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82473. *
  82474. * For the full copyright and license information, please view the LICENSE
  82475. * file that was distributed with this source code.
  82476. */
  82477. namespace PHPUnit\TextUI\XmlConfiguration;
  82478. use PHPUnit\TextUI\Configuration\Exception;
  82479. use RuntimeException;
  82480. /**
  82481. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82482. *
  82483. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82484. */
  82485. final class CannotFindSchemaException extends RuntimeException implements Exception
  82486. {
  82487. }
  82488. <?php
  82489. declare (strict_types=1);
  82490. /*
  82491. * This file is part of PHPUnit.
  82492. *
  82493. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82494. *
  82495. * For the full copyright and license information, please view the LICENSE
  82496. * file that was distributed with this source code.
  82497. */
  82498. namespace PHPUnit\TextUI\Configuration;
  82499. use RuntimeException;
  82500. /**
  82501. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82502. *
  82503. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82504. */
  82505. final class CodeCoverageReportNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82506. {
  82507. }
  82508. <?php
  82509. declare (strict_types=1);
  82510. /*
  82511. * This file is part of PHPUnit.
  82512. *
  82513. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82514. *
  82515. * For the full copyright and license information, please view the LICENSE
  82516. * file that was distributed with this source code.
  82517. */
  82518. namespace PHPUnit\TextUI\Configuration;
  82519. use RuntimeException;
  82520. /**
  82521. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82522. *
  82523. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82524. */
  82525. final class ConfigurationCannotBeBuiltException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82526. {
  82527. }
  82528. <?php
  82529. declare (strict_types=1);
  82530. /*
  82531. * This file is part of PHPUnit.
  82532. *
  82533. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82534. *
  82535. * For the full copyright and license information, please view the LICENSE
  82536. * file that was distributed with this source code.
  82537. */
  82538. namespace PHPUnit\TextUI\Configuration;
  82539. /**
  82540. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82541. *
  82542. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  82543. */
  82544. interface Exception extends \PHPUnit\TextUI\Exception
  82545. {
  82546. }
  82547. <?php
  82548. declare (strict_types=1);
  82549. /*
  82550. * This file is part of PHPUnit.
  82551. *
  82552. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82553. *
  82554. * For the full copyright and license information, please view the LICENSE
  82555. * file that was distributed with this source code.
  82556. */
  82557. namespace PHPUnit\TextUI\Configuration;
  82558. use RuntimeException;
  82559. /**
  82560. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82561. *
  82562. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82563. */
  82564. final class FilterNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82565. {
  82566. }
  82567. <?php
  82568. declare (strict_types=1);
  82569. /*
  82570. * This file is part of PHPUnit.
  82571. *
  82572. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82573. *
  82574. * For the full copyright and license information, please view the LICENSE
  82575. * file that was distributed with this source code.
  82576. */
  82577. namespace PHPUnit\TextUI\Configuration;
  82578. use RuntimeException;
  82579. /**
  82580. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82581. *
  82582. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82583. */
  82584. final class LoggingNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82585. {
  82586. }
  82587. <?php
  82588. declare (strict_types=1);
  82589. /*
  82590. * This file is part of PHPUnit.
  82591. *
  82592. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82593. *
  82594. * For the full copyright and license information, please view the LICENSE
  82595. * file that was distributed with this source code.
  82596. */
  82597. namespace PHPUnit\TextUI\Configuration;
  82598. use RuntimeException;
  82599. /**
  82600. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82601. *
  82602. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82603. */
  82604. final class NoBaselineException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82605. {
  82606. }
  82607. <?php
  82608. declare (strict_types=1);
  82609. /*
  82610. * This file is part of PHPUnit.
  82611. *
  82612. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82613. *
  82614. * For the full copyright and license information, please view the LICENSE
  82615. * file that was distributed with this source code.
  82616. */
  82617. namespace PHPUnit\TextUI\Configuration;
  82618. use RuntimeException;
  82619. /**
  82620. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82621. *
  82622. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82623. */
  82624. final class NoBootstrapException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82625. {
  82626. }
  82627. <?php
  82628. declare (strict_types=1);
  82629. /*
  82630. * This file is part of PHPUnit.
  82631. *
  82632. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82633. *
  82634. * For the full copyright and license information, please view the LICENSE
  82635. * file that was distributed with this source code.
  82636. */
  82637. namespace PHPUnit\TextUI\Configuration;
  82638. use RuntimeException;
  82639. /**
  82640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82641. *
  82642. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82643. */
  82644. final class NoCacheDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82645. {
  82646. }
  82647. <?php
  82648. declare (strict_types=1);
  82649. /*
  82650. * This file is part of PHPUnit.
  82651. *
  82652. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82653. *
  82654. * For the full copyright and license information, please view the LICENSE
  82655. * file that was distributed with this source code.
  82656. */
  82657. namespace PHPUnit\TextUI\Configuration;
  82658. use RuntimeException;
  82659. /**
  82660. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82661. *
  82662. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82663. */
  82664. final class NoCliArgumentException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82665. {
  82666. }
  82667. <?php
  82668. declare (strict_types=1);
  82669. /*
  82670. * This file is part of PHPUnit.
  82671. *
  82672. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82673. *
  82674. * For the full copyright and license information, please view the LICENSE
  82675. * file that was distributed with this source code.
  82676. */
  82677. namespace PHPUnit\TextUI\Configuration;
  82678. use RuntimeException;
  82679. /**
  82680. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82681. *
  82682. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82683. */
  82684. final class NoConfigurationFileException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82685. {
  82686. }
  82687. <?php
  82688. declare (strict_types=1);
  82689. /*
  82690. * This file is part of PHPUnit.
  82691. *
  82692. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82693. *
  82694. * For the full copyright and license information, please view the LICENSE
  82695. * file that was distributed with this source code.
  82696. */
  82697. namespace PHPUnit\TextUI\Configuration;
  82698. use RuntimeException;
  82699. /**
  82700. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82701. *
  82702. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82703. */
  82704. final class NoCoverageCacheDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82705. {
  82706. }
  82707. <?php
  82708. declare (strict_types=1);
  82709. /*
  82710. * This file is part of PHPUnit.
  82711. *
  82712. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82713. *
  82714. * For the full copyright and license information, please view the LICENSE
  82715. * file that was distributed with this source code.
  82716. */
  82717. namespace PHPUnit\TextUI\Configuration;
  82718. use RuntimeException;
  82719. /**
  82720. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82721. *
  82722. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82723. */
  82724. final class NoCustomCssFileException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82725. {
  82726. }
  82727. <?php
  82728. declare (strict_types=1);
  82729. /*
  82730. * This file is part of PHPUnit.
  82731. *
  82732. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82733. *
  82734. * For the full copyright and license information, please view the LICENSE
  82735. * file that was distributed with this source code.
  82736. */
  82737. namespace PHPUnit\TextUI\Configuration;
  82738. use RuntimeException;
  82739. /**
  82740. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82741. *
  82742. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82743. */
  82744. final class NoDefaultTestSuiteException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82745. {
  82746. }
  82747. <?php
  82748. declare (strict_types=1);
  82749. /*
  82750. * This file is part of PHPUnit.
  82751. *
  82752. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82753. *
  82754. * For the full copyright and license information, please view the LICENSE
  82755. * file that was distributed with this source code.
  82756. */
  82757. namespace PHPUnit\TextUI\Configuration;
  82758. use RuntimeException;
  82759. /**
  82760. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82761. *
  82762. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82763. */
  82764. final class NoPharExtensionDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
  82765. {
  82766. }
  82767. <?php
  82768. declare (strict_types=1);
  82769. /*
  82770. * This file is part of PHPUnit.
  82771. *
  82772. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  82773. *
  82774. * For the full copyright and license information, please view the LICENSE
  82775. * file that was distributed with this source code.
  82776. */
  82777. namespace PHPUnit\TextUI\Configuration;
  82778. use const DIRECTORY_SEPARATOR;
  82779. use const PATH_SEPARATOR;
  82780. use function array_diff;
  82781. use function assert;
  82782. use function dirname;
  82783. use function explode;
  82784. use function is_int;
  82785. use function realpath;
  82786. use function time;
  82787. use PHPUnit\Event\Facade as EventFacade;
  82788. use PHPUnit\Runner\TestSuiteSorter;
  82789. use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
  82790. use PHPUnit\TextUI\CliArguments\Exception;
  82791. use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
  82792. use PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration;
  82793. use PHPUnit\TextUI\XmlConfiguration\SchemaDetector;
  82794. use PHPUnit\Util\Filesystem;
  82795. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
  82796. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
  82797. use PHPUnitPHAR\SebastianBergmann\Environment\Console;
  82798. use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
  82799. /**
  82800. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  82801. *
  82802. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  82803. */
  82804. final class Merger
  82805. {
  82806. /**
  82807. * @throws \PHPUnit\TextUI\XmlConfiguration\Exception
  82808. * @throws Exception
  82809. * @throws NoCustomCssFileException
  82810. */
  82811. public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): \PHPUnit\TextUI\Configuration\Configuration
  82812. {
  82813. $configurationFile = null;
  82814. if ($xmlConfiguration->wasLoadedFromFile()) {
  82815. assert($xmlConfiguration instanceof LoadedFromFileConfiguration);
  82816. $configurationFile = $xmlConfiguration->filename();
  82817. }
  82818. $bootstrap = null;
  82819. if ($cliConfiguration->hasBootstrap()) {
  82820. $bootstrap = $cliConfiguration->bootstrap();
  82821. } elseif ($xmlConfiguration->phpunit()->hasBootstrap()) {
  82822. $bootstrap = $xmlConfiguration->phpunit()->bootstrap();
  82823. }
  82824. if ($cliConfiguration->hasCacheResult()) {
  82825. $cacheResult = $cliConfiguration->cacheResult();
  82826. } else {
  82827. $cacheResult = $xmlConfiguration->phpunit()->cacheResult();
  82828. }
  82829. $cacheDirectory = null;
  82830. $coverageCacheDirectory = null;
  82831. if ($cliConfiguration->hasCacheDirectory() && Filesystem::createDirectory($cliConfiguration->cacheDirectory())) {
  82832. $cacheDirectory = realpath($cliConfiguration->cacheDirectory());
  82833. } elseif ($xmlConfiguration->phpunit()->hasCacheDirectory() && Filesystem::createDirectory($xmlConfiguration->phpunit()->cacheDirectory())) {
  82834. $cacheDirectory = realpath($xmlConfiguration->phpunit()->cacheDirectory());
  82835. }
  82836. if ($cacheDirectory !== null) {
  82837. $coverageCacheDirectory = $cacheDirectory . DIRECTORY_SEPARATOR . 'code-coverage';
  82838. $testResultCacheFile = $cacheDirectory . DIRECTORY_SEPARATOR . 'test-results';
  82839. }
  82840. if ($coverageCacheDirectory === null) {
  82841. if ($cliConfiguration->hasCoverageCacheDirectory() && Filesystem::createDirectory($cliConfiguration->coverageCacheDirectory())) {
  82842. $coverageCacheDirectory = realpath($cliConfiguration->coverageCacheDirectory());
  82843. } elseif ($xmlConfiguration->codeCoverage()->hasCacheDirectory()) {
  82844. $coverageCacheDirectory = $xmlConfiguration->codeCoverage()->cacheDirectory()->path();
  82845. }
  82846. }
  82847. if (!isset($testResultCacheFile)) {
  82848. if ($cliConfiguration->hasCacheResultFile()) {
  82849. $testResultCacheFile = $cliConfiguration->cacheResultFile();
  82850. } elseif ($xmlConfiguration->phpunit()->hasCacheResultFile()) {
  82851. $testResultCacheFile = $xmlConfiguration->phpunit()->cacheResultFile();
  82852. } elseif ($xmlConfiguration->wasLoadedFromFile()) {
  82853. $testResultCacheFile = dirname(realpath($xmlConfiguration->filename())) . DIRECTORY_SEPARATOR . '.phpunit.result.cache';
  82854. } else {
  82855. $candidate = realpath($_SERVER['PHP_SELF']);
  82856. if ($candidate) {
  82857. $testResultCacheFile = dirname($candidate) . DIRECTORY_SEPARATOR . '.phpunit.result.cache';
  82858. } else {
  82859. $testResultCacheFile = '.phpunit.result.cache';
  82860. }
  82861. }
  82862. }
  82863. if ($cliConfiguration->hasDisableCodeCoverageIgnore()) {
  82864. $disableCodeCoverageIgnore = $cliConfiguration->disableCodeCoverageIgnore();
  82865. } else {
  82866. $disableCodeCoverageIgnore = $xmlConfiguration->codeCoverage()->disableCodeCoverageIgnore();
  82867. }
  82868. if ($cliConfiguration->hasFailOnDeprecation()) {
  82869. $failOnDeprecation = $cliConfiguration->failOnDeprecation();
  82870. } else {
  82871. $failOnDeprecation = $xmlConfiguration->phpunit()->failOnDeprecation();
  82872. }
  82873. if ($cliConfiguration->hasFailOnPhpunitDeprecation()) {
  82874. $failOnPhpunitDeprecation = $cliConfiguration->failOnPhpunitDeprecation();
  82875. } else {
  82876. $failOnPhpunitDeprecation = $xmlConfiguration->phpunit()->failOnPhpunitDeprecation();
  82877. }
  82878. if ($cliConfiguration->hasFailOnEmptyTestSuite()) {
  82879. $failOnEmptyTestSuite = $cliConfiguration->failOnEmptyTestSuite();
  82880. } else {
  82881. $failOnEmptyTestSuite = $xmlConfiguration->phpunit()->failOnEmptyTestSuite();
  82882. }
  82883. if ($cliConfiguration->hasFailOnIncomplete()) {
  82884. $failOnIncomplete = $cliConfiguration->failOnIncomplete();
  82885. } else {
  82886. $failOnIncomplete = $xmlConfiguration->phpunit()->failOnIncomplete();
  82887. }
  82888. if ($cliConfiguration->hasFailOnNotice()) {
  82889. $failOnNotice = $cliConfiguration->failOnNotice();
  82890. } else {
  82891. $failOnNotice = $xmlConfiguration->phpunit()->failOnNotice();
  82892. }
  82893. if ($cliConfiguration->hasFailOnRisky()) {
  82894. $failOnRisky = $cliConfiguration->failOnRisky();
  82895. } else {
  82896. $failOnRisky = $xmlConfiguration->phpunit()->failOnRisky();
  82897. }
  82898. if ($cliConfiguration->hasFailOnSkipped()) {
  82899. $failOnSkipped = $cliConfiguration->failOnSkipped();
  82900. } else {
  82901. $failOnSkipped = $xmlConfiguration->phpunit()->failOnSkipped();
  82902. }
  82903. if ($cliConfiguration->hasFailOnWarning()) {
  82904. $failOnWarning = $cliConfiguration->failOnWarning();
  82905. } else {
  82906. $failOnWarning = $xmlConfiguration->phpunit()->failOnWarning();
  82907. }
  82908. if ($cliConfiguration->hasStopOnDefect()) {
  82909. $stopOnDefect = $cliConfiguration->stopOnDefect();
  82910. } else {
  82911. $stopOnDefect = $xmlConfiguration->phpunit()->stopOnDefect();
  82912. }
  82913. if ($cliConfiguration->hasStopOnDeprecation()) {
  82914. $stopOnDeprecation = $cliConfiguration->stopOnDeprecation();
  82915. } else {
  82916. $stopOnDeprecation = $xmlConfiguration->phpunit()->stopOnDeprecation();
  82917. }
  82918. if ($cliConfiguration->hasStopOnError()) {
  82919. $stopOnError = $cliConfiguration->stopOnError();
  82920. } else {
  82921. $stopOnError = $xmlConfiguration->phpunit()->stopOnError();
  82922. }
  82923. if ($cliConfiguration->hasStopOnFailure()) {
  82924. $stopOnFailure = $cliConfiguration->stopOnFailure();
  82925. } else {
  82926. $stopOnFailure = $xmlConfiguration->phpunit()->stopOnFailure();
  82927. }
  82928. if ($cliConfiguration->hasStopOnIncomplete()) {
  82929. $stopOnIncomplete = $cliConfiguration->stopOnIncomplete();
  82930. } else {
  82931. $stopOnIncomplete = $xmlConfiguration->phpunit()->stopOnIncomplete();
  82932. }
  82933. if ($cliConfiguration->hasStopOnNotice()) {
  82934. $stopOnNotice = $cliConfiguration->stopOnNotice();
  82935. } else {
  82936. $stopOnNotice = $xmlConfiguration->phpunit()->stopOnNotice();
  82937. }
  82938. if ($cliConfiguration->hasStopOnRisky()) {
  82939. $stopOnRisky = $cliConfiguration->stopOnRisky();
  82940. } else {
  82941. $stopOnRisky = $xmlConfiguration->phpunit()->stopOnRisky();
  82942. }
  82943. if ($cliConfiguration->hasStopOnSkipped()) {
  82944. $stopOnSkipped = $cliConfiguration->stopOnSkipped();
  82945. } else {
  82946. $stopOnSkipped = $xmlConfiguration->phpunit()->stopOnSkipped();
  82947. }
  82948. if ($cliConfiguration->hasStopOnWarning()) {
  82949. $stopOnWarning = $cliConfiguration->stopOnWarning();
  82950. } else {
  82951. $stopOnWarning = $xmlConfiguration->phpunit()->stopOnWarning();
  82952. }
  82953. if ($cliConfiguration->hasStderr() && $cliConfiguration->stderr()) {
  82954. $outputToStandardErrorStream = \true;
  82955. } else {
  82956. $outputToStandardErrorStream = $xmlConfiguration->phpunit()->stderr();
  82957. }
  82958. if ($cliConfiguration->hasColumns()) {
  82959. $columns = $cliConfiguration->columns();
  82960. } else {
  82961. $columns = $xmlConfiguration->phpunit()->columns();
  82962. }
  82963. if ($columns === 'max') {
  82964. $columns = (new Console())->getNumberOfColumns();
  82965. }
  82966. if ($columns < 16) {
  82967. $columns = 16;
  82968. EventFacade::emitter()->testRunnerTriggeredWarning('Less than 16 columns requested, number of columns set to 16');
  82969. }
  82970. assert(is_int($columns));
  82971. $noExtensions = \false;
  82972. if ($cliConfiguration->hasNoExtensions() && $cliConfiguration->noExtensions()) {
  82973. $noExtensions = \true;
  82974. }
  82975. $pharExtensionDirectory = null;
  82976. if ($xmlConfiguration->phpunit()->hasExtensionsDirectory()) {
  82977. $pharExtensionDirectory = $xmlConfiguration->phpunit()->extensionsDirectory();
  82978. }
  82979. $extensionBootstrappers = [];
  82980. foreach ($xmlConfiguration->extensions() as $extension) {
  82981. $extensionBootstrappers[] = ['className' => $extension->className(), 'parameters' => $extension->parameters()];
  82982. }
  82983. if ($cliConfiguration->hasPathCoverage() && $cliConfiguration->pathCoverage()) {
  82984. $pathCoverage = $cliConfiguration->pathCoverage();
  82985. } else {
  82986. $pathCoverage = $xmlConfiguration->codeCoverage()->pathCoverage();
  82987. }
  82988. $defaultColors = Colors::default();
  82989. $defaultThresholds = Thresholds::default();
  82990. $coverageClover = null;
  82991. $coverageCobertura = null;
  82992. $coverageCrap4j = null;
  82993. $coverageCrap4jThreshold = 30;
  82994. $coverageHtml = null;
  82995. $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound();
  82996. $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound();
  82997. $coverageHtmlColorSuccessLow = $defaultColors->successLow();
  82998. $coverageHtmlColorSuccessMedium = $defaultColors->successMedium();
  82999. $coverageHtmlColorSuccessHigh = $defaultColors->successHigh();
  83000. $coverageHtmlColorWarning = $defaultColors->warning();
  83001. $coverageHtmlColorDanger = $defaultColors->danger();
  83002. $coverageHtmlCustomCssFile = null;
  83003. $coveragePhp = null;
  83004. $coverageText = null;
  83005. $coverageTextShowUncoveredFiles = \false;
  83006. $coverageTextShowOnlySummary = \false;
  83007. $coverageXml = null;
  83008. $coverageFromXmlConfiguration = \true;
  83009. if ($cliConfiguration->hasNoCoverage() && $cliConfiguration->noCoverage()) {
  83010. $coverageFromXmlConfiguration = \false;
  83011. }
  83012. if ($cliConfiguration->hasCoverageClover()) {
  83013. $coverageClover = $cliConfiguration->coverageClover();
  83014. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasClover()) {
  83015. $coverageClover = $xmlConfiguration->codeCoverage()->clover()->target()->path();
  83016. }
  83017. if ($cliConfiguration->hasCoverageCobertura()) {
  83018. $coverageCobertura = $cliConfiguration->coverageCobertura();
  83019. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCobertura()) {
  83020. $coverageCobertura = $xmlConfiguration->codeCoverage()->cobertura()->target()->path();
  83021. }
  83022. if ($xmlConfiguration->codeCoverage()->hasCrap4j()) {
  83023. $coverageCrap4jThreshold = $xmlConfiguration->codeCoverage()->crap4j()->threshold();
  83024. }
  83025. if ($cliConfiguration->hasCoverageCrap4J()) {
  83026. $coverageCrap4j = $cliConfiguration->coverageCrap4J();
  83027. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCrap4j()) {
  83028. $coverageCrap4j = $xmlConfiguration->codeCoverage()->crap4j()->target()->path();
  83029. }
  83030. if ($xmlConfiguration->codeCoverage()->hasHtml()) {
  83031. $coverageHtmlHighLowerBound = $xmlConfiguration->codeCoverage()->html()->highLowerBound();
  83032. $coverageHtmlLowUpperBound = $xmlConfiguration->codeCoverage()->html()->lowUpperBound();
  83033. if ($coverageHtmlLowUpperBound > $coverageHtmlHighLowerBound) {
  83034. $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound();
  83035. $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound();
  83036. }
  83037. $coverageHtmlColorSuccessLow = $xmlConfiguration->codeCoverage()->html()->colorSuccessLow();
  83038. $coverageHtmlColorSuccessMedium = $xmlConfiguration->codeCoverage()->html()->colorSuccessMedium();
  83039. $coverageHtmlColorSuccessHigh = $xmlConfiguration->codeCoverage()->html()->colorSuccessHigh();
  83040. $coverageHtmlColorWarning = $xmlConfiguration->codeCoverage()->html()->colorWarning();
  83041. $coverageHtmlColorDanger = $xmlConfiguration->codeCoverage()->html()->colorDanger();
  83042. if ($xmlConfiguration->codeCoverage()->html()->hasCustomCssFile()) {
  83043. $coverageHtmlCustomCssFile = $xmlConfiguration->codeCoverage()->html()->customCssFile();
  83044. }
  83045. }
  83046. if ($cliConfiguration->hasCoverageHtml()) {
  83047. $coverageHtml = $cliConfiguration->coverageHtml();
  83048. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasHtml()) {
  83049. $coverageHtml = $xmlConfiguration->codeCoverage()->html()->target()->path();
  83050. }
  83051. if ($cliConfiguration->hasCoveragePhp()) {
  83052. $coveragePhp = $cliConfiguration->coveragePhp();
  83053. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasPhp()) {
  83054. $coveragePhp = $xmlConfiguration->codeCoverage()->php()->target()->path();
  83055. }
  83056. if ($xmlConfiguration->codeCoverage()->hasText()) {
  83057. $coverageTextShowUncoveredFiles = $xmlConfiguration->codeCoverage()->text()->showUncoveredFiles();
  83058. $coverageTextShowOnlySummary = $xmlConfiguration->codeCoverage()->text()->showOnlySummary();
  83059. }
  83060. if ($cliConfiguration->hasCoverageTextShowUncoveredFiles()) {
  83061. $coverageTextShowUncoveredFiles = $cliConfiguration->coverageTextShowUncoveredFiles();
  83062. }
  83063. if ($cliConfiguration->hasCoverageTextShowOnlySummary()) {
  83064. $coverageTextShowOnlySummary = $cliConfiguration->coverageTextShowOnlySummary();
  83065. }
  83066. if ($cliConfiguration->hasCoverageText()) {
  83067. $coverageText = $cliConfiguration->coverageText();
  83068. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasText()) {
  83069. $coverageText = $xmlConfiguration->codeCoverage()->text()->target()->path();
  83070. }
  83071. if ($cliConfiguration->hasCoverageXml()) {
  83072. $coverageXml = $cliConfiguration->coverageXml();
  83073. } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasXml()) {
  83074. $coverageXml = $xmlConfiguration->codeCoverage()->xml()->target()->path();
  83075. }
  83076. if ($cliConfiguration->hasBackupGlobals()) {
  83077. $backupGlobals = $cliConfiguration->backupGlobals();
  83078. } else {
  83079. $backupGlobals = $xmlConfiguration->phpunit()->backupGlobals();
  83080. }
  83081. if ($cliConfiguration->hasBackupStaticProperties()) {
  83082. $backupStaticProperties = $cliConfiguration->backupStaticProperties();
  83083. } else {
  83084. $backupStaticProperties = $xmlConfiguration->phpunit()->backupStaticProperties();
  83085. }
  83086. if ($cliConfiguration->hasBeStrictAboutChangesToGlobalState()) {
  83087. $beStrictAboutChangesToGlobalState = $cliConfiguration->beStrictAboutChangesToGlobalState();
  83088. } else {
  83089. $beStrictAboutChangesToGlobalState = $xmlConfiguration->phpunit()->beStrictAboutChangesToGlobalState();
  83090. }
  83091. if ($cliConfiguration->hasProcessIsolation()) {
  83092. $processIsolation = $cliConfiguration->processIsolation();
  83093. } else {
  83094. $processIsolation = $xmlConfiguration->phpunit()->processIsolation();
  83095. }
  83096. if ($cliConfiguration->hasEnforceTimeLimit()) {
  83097. $enforceTimeLimit = $cliConfiguration->enforceTimeLimit();
  83098. } else {
  83099. $enforceTimeLimit = $xmlConfiguration->phpunit()->enforceTimeLimit();
  83100. }
  83101. if ($enforceTimeLimit && !(new Invoker())->canInvokeWithTimeout()) {
  83102. EventFacade::emitter()->testRunnerTriggeredWarning('The pcntl extension is required for enforcing time limits');
  83103. }
  83104. if ($cliConfiguration->hasDefaultTimeLimit()) {
  83105. $defaultTimeLimit = $cliConfiguration->defaultTimeLimit();
  83106. } else {
  83107. $defaultTimeLimit = $xmlConfiguration->phpunit()->defaultTimeLimit();
  83108. }
  83109. $timeoutForSmallTests = $xmlConfiguration->phpunit()->timeoutForSmallTests();
  83110. $timeoutForMediumTests = $xmlConfiguration->phpunit()->timeoutForMediumTests();
  83111. $timeoutForLargeTests = $xmlConfiguration->phpunit()->timeoutForLargeTests();
  83112. if ($cliConfiguration->hasReportUselessTests()) {
  83113. $reportUselessTests = $cliConfiguration->reportUselessTests();
  83114. } else {
  83115. $reportUselessTests = $xmlConfiguration->phpunit()->beStrictAboutTestsThatDoNotTestAnything();
  83116. }
  83117. if ($cliConfiguration->hasStrictCoverage()) {
  83118. $strictCoverage = $cliConfiguration->strictCoverage();
  83119. } else {
  83120. $strictCoverage = $xmlConfiguration->phpunit()->beStrictAboutCoverageMetadata();
  83121. }
  83122. if ($cliConfiguration->hasDisallowTestOutput()) {
  83123. $disallowTestOutput = $cliConfiguration->disallowTestOutput();
  83124. } else {
  83125. $disallowTestOutput = $xmlConfiguration->phpunit()->beStrictAboutOutputDuringTests();
  83126. }
  83127. if ($cliConfiguration->hasDisplayDetailsOnIncompleteTests()) {
  83128. $displayDetailsOnIncompleteTests = $cliConfiguration->displayDetailsOnIncompleteTests();
  83129. } else {
  83130. $displayDetailsOnIncompleteTests = $xmlConfiguration->phpunit()->displayDetailsOnIncompleteTests();
  83131. }
  83132. if ($cliConfiguration->hasDisplayDetailsOnSkippedTests()) {
  83133. $displayDetailsOnSkippedTests = $cliConfiguration->displayDetailsOnSkippedTests();
  83134. } else {
  83135. $displayDetailsOnSkippedTests = $xmlConfiguration->phpunit()->displayDetailsOnSkippedTests();
  83136. }
  83137. if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerDeprecations()) {
  83138. $displayDetailsOnTestsThatTriggerDeprecations = $cliConfiguration->displayDetailsOnTestsThatTriggerDeprecations();
  83139. } else {
  83140. $displayDetailsOnTestsThatTriggerDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerDeprecations();
  83141. }
  83142. if ($cliConfiguration->hasDisplayDetailsOnPhpunitDeprecations()) {
  83143. $displayDetailsOnPhpunitDeprecations = $cliConfiguration->displayDetailsOnPhpunitDeprecations();
  83144. } else {
  83145. $displayDetailsOnPhpunitDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnPhpunitDeprecations();
  83146. }
  83147. if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerErrors()) {
  83148. $displayDetailsOnTestsThatTriggerErrors = $cliConfiguration->displayDetailsOnTestsThatTriggerErrors();
  83149. } else {
  83150. $displayDetailsOnTestsThatTriggerErrors = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerErrors();
  83151. }
  83152. if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerNotices()) {
  83153. $displayDetailsOnTestsThatTriggerNotices = $cliConfiguration->displayDetailsOnTestsThatTriggerNotices();
  83154. } else {
  83155. $displayDetailsOnTestsThatTriggerNotices = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerNotices();
  83156. }
  83157. if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerWarnings()) {
  83158. $displayDetailsOnTestsThatTriggerWarnings = $cliConfiguration->displayDetailsOnTestsThatTriggerWarnings();
  83159. } else {
  83160. $displayDetailsOnTestsThatTriggerWarnings = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerWarnings();
  83161. }
  83162. if ($cliConfiguration->hasReverseList()) {
  83163. $reverseDefectList = $cliConfiguration->reverseList();
  83164. } else {
  83165. $reverseDefectList = $xmlConfiguration->phpunit()->reverseDefectList();
  83166. }
  83167. $requireCoverageMetadata = $xmlConfiguration->phpunit()->requireCoverageMetadata();
  83168. $registerMockObjectsFromTestArgumentsRecursively = $xmlConfiguration->phpunit()->registerMockObjectsFromTestArgumentsRecursively();
  83169. if ($cliConfiguration->hasExecutionOrder()) {
  83170. $executionOrder = $cliConfiguration->executionOrder();
  83171. } else {
  83172. $executionOrder = $xmlConfiguration->phpunit()->executionOrder();
  83173. }
  83174. $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT;
  83175. if ($cliConfiguration->hasExecutionOrderDefects()) {
  83176. $executionOrderDefects = $cliConfiguration->executionOrderDefects();
  83177. } elseif ($xmlConfiguration->phpunit()->defectsFirst()) {
  83178. $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST;
  83179. }
  83180. if ($cliConfiguration->hasResolveDependencies()) {
  83181. $resolveDependencies = $cliConfiguration->resolveDependencies();
  83182. } else {
  83183. $resolveDependencies = $xmlConfiguration->phpunit()->resolveDependencies();
  83184. }
  83185. $colors = \false;
  83186. $colorsSupported = (new Console())->hasColorSupport();
  83187. if ($cliConfiguration->hasColors()) {
  83188. if ($cliConfiguration->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_ALWAYS) {
  83189. $colors = \true;
  83190. } elseif ($colorsSupported && $cliConfiguration->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO) {
  83191. $colors = \true;
  83192. }
  83193. } elseif ($xmlConfiguration->phpunit()->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_ALWAYS) {
  83194. $colors = \true;
  83195. } elseif ($colorsSupported && $xmlConfiguration->phpunit()->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO) {
  83196. $colors = \true;
  83197. }
  83198. $logfileTeamcity = null;
  83199. $logfileJunit = null;
  83200. $logfileTestdoxHtml = null;
  83201. $logfileTestdoxText = null;
  83202. $loggingFromXmlConfiguration = \true;
  83203. if ($cliConfiguration->hasNoLogging() && $cliConfiguration->noLogging()) {
  83204. $loggingFromXmlConfiguration = \false;
  83205. }
  83206. if ($cliConfiguration->hasTeamcityLogfile()) {
  83207. $logfileTeamcity = $cliConfiguration->teamcityLogfile();
  83208. } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTeamCity()) {
  83209. $logfileTeamcity = $xmlConfiguration->logging()->teamCity()->target()->path();
  83210. }
  83211. if ($cliConfiguration->hasJunitLogfile()) {
  83212. $logfileJunit = $cliConfiguration->junitLogfile();
  83213. } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasJunit()) {
  83214. $logfileJunit = $xmlConfiguration->logging()->junit()->target()->path();
  83215. }
  83216. if ($cliConfiguration->hasTestdoxHtmlFile()) {
  83217. $logfileTestdoxHtml = $cliConfiguration->testdoxHtmlFile();
  83218. } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxHtml()) {
  83219. $logfileTestdoxHtml = $xmlConfiguration->logging()->testDoxHtml()->target()->path();
  83220. }
  83221. if ($cliConfiguration->hasTestdoxTextFile()) {
  83222. $logfileTestdoxText = $cliConfiguration->testdoxTextFile();
  83223. } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxText()) {
  83224. $logfileTestdoxText = $xmlConfiguration->logging()->testDoxText()->target()->path();
  83225. }
  83226. $logEventsText = null;
  83227. if ($cliConfiguration->hasLogEventsText()) {
  83228. $logEventsText = $cliConfiguration->logEventsText();
  83229. }
  83230. $logEventsVerboseText = null;
  83231. if ($cliConfiguration->hasLogEventsVerboseText()) {
  83232. $logEventsVerboseText = $cliConfiguration->logEventsVerboseText();
  83233. }
  83234. $teamCityOutput = \false;
  83235. if ($cliConfiguration->hasTeamCityPrinter() && $cliConfiguration->teamCityPrinter()) {
  83236. $teamCityOutput = \true;
  83237. }
  83238. if ($cliConfiguration->hasTestDoxPrinter() && $cliConfiguration->testdoxPrinter()) {
  83239. $testDoxOutput = \true;
  83240. } else {
  83241. $testDoxOutput = $xmlConfiguration->phpunit()->testdoxPrinter();
  83242. }
  83243. $noProgress = \false;
  83244. if ($cliConfiguration->hasNoProgress() && $cliConfiguration->noProgress()) {
  83245. $noProgress = \true;
  83246. }
  83247. $noResults = \false;
  83248. if ($cliConfiguration->hasNoResults() && $cliConfiguration->noResults()) {
  83249. $noResults = \true;
  83250. }
  83251. $noOutput = \false;
  83252. if ($cliConfiguration->hasNoOutput() && $cliConfiguration->noOutput()) {
  83253. $noOutput = \true;
  83254. }
  83255. $testsCovering = null;
  83256. if ($cliConfiguration->hasTestsCovering()) {
  83257. $testsCovering = $cliConfiguration->testsCovering();
  83258. }
  83259. $testsUsing = null;
  83260. if ($cliConfiguration->hasTestsUsing()) {
  83261. $testsUsing = $cliConfiguration->testsUsing();
  83262. }
  83263. $filter = null;
  83264. if ($cliConfiguration->hasFilter()) {
  83265. $filter = $cliConfiguration->filter();
  83266. }
  83267. if ($cliConfiguration->hasGroups()) {
  83268. $groups = $cliConfiguration->groups();
  83269. } else {
  83270. $groups = $xmlConfiguration->groups()->include()->asArrayOfStrings();
  83271. }
  83272. if ($cliConfiguration->hasExcludeGroups()) {
  83273. $excludeGroups = $cliConfiguration->excludeGroups();
  83274. } else {
  83275. $excludeGroups = $xmlConfiguration->groups()->exclude()->asArrayOfStrings();
  83276. }
  83277. $excludeGroups = array_diff($excludeGroups, $groups);
  83278. if ($cliConfiguration->hasRandomOrderSeed()) {
  83279. $randomOrderSeed = $cliConfiguration->randomOrderSeed();
  83280. } else {
  83281. $randomOrderSeed = time();
  83282. }
  83283. if ($xmlConfiguration->wasLoadedFromFile() && $xmlConfiguration->hasValidationErrors()) {
  83284. if ((new SchemaDetector())->detect($xmlConfiguration->filename())->detected()) {
  83285. EventFacade::emitter()->testRunnerTriggeredDeprecation('Your XML configuration validates against a deprecated schema. Migrate your XML configuration using "--migrate-configuration"!');
  83286. } else {
  83287. EventFacade::emitter()->testRunnerTriggeredWarning("Test results may not be as expected because the XML configuration file did not pass validation:\n" . $xmlConfiguration->validationErrors());
  83288. }
  83289. }
  83290. $includeUncoveredFiles = $xmlConfiguration->codeCoverage()->includeUncoveredFiles();
  83291. $includePaths = [];
  83292. if ($cliConfiguration->hasIncludePath()) {
  83293. foreach (explode(PATH_SEPARATOR, $cliConfiguration->includePath()) as $includePath) {
  83294. $includePaths[] = new \PHPUnit\TextUI\Configuration\Directory($includePath);
  83295. }
  83296. }
  83297. foreach ($xmlConfiguration->php()->includePaths() as $includePath) {
  83298. $includePaths[] = $includePath;
  83299. }
  83300. $iniSettings = [];
  83301. if ($cliConfiguration->hasIniSettings()) {
  83302. foreach ($cliConfiguration->iniSettings() as $name => $value) {
  83303. $iniSettings[] = new \PHPUnit\TextUI\Configuration\IniSetting($name, $value);
  83304. }
  83305. }
  83306. foreach ($xmlConfiguration->php()->iniSettings() as $iniSetting) {
  83307. $iniSettings[] = $iniSetting;
  83308. }
  83309. $includeTestSuite = '';
  83310. if ($cliConfiguration->hasTestSuite()) {
  83311. $includeTestSuite = $cliConfiguration->testSuite();
  83312. } elseif ($xmlConfiguration->phpunit()->hasDefaultTestSuite()) {
  83313. $includeTestSuite = $xmlConfiguration->phpunit()->defaultTestSuite();
  83314. }
  83315. $excludeTestSuite = '';
  83316. if ($cliConfiguration->hasExcludedTestSuite()) {
  83317. $excludeTestSuite = $cliConfiguration->excludedTestSuite();
  83318. }
  83319. $testSuffixes = ['Test.php', '.phpt'];
  83320. if ($cliConfiguration->hasTestSuffixes()) {
  83321. $testSuffixes = $cliConfiguration->testSuffixes();
  83322. }
  83323. $sourceIncludeDirectories = [];
  83324. if ($cliConfiguration->hasCoverageFilter()) {
  83325. foreach ($cliConfiguration->coverageFilter() as $directory) {
  83326. $sourceIncludeDirectories[] = new \PHPUnit\TextUI\Configuration\FilterDirectory($directory, '', '.php');
  83327. }
  83328. }
  83329. if ($xmlConfiguration->codeCoverage()->hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport()) {
  83330. foreach ($xmlConfiguration->codeCoverage()->directories() as $directory) {
  83331. $sourceIncludeDirectories[] = $directory;
  83332. }
  83333. $sourceIncludeFiles = $xmlConfiguration->codeCoverage()->files();
  83334. $sourceExcludeDirectories = $xmlConfiguration->codeCoverage()->excludeDirectories();
  83335. $sourceExcludeFiles = $xmlConfiguration->codeCoverage()->excludeFiles();
  83336. } else {
  83337. foreach ($xmlConfiguration->source()->includeDirectories() as $directory) {
  83338. $sourceIncludeDirectories[] = $directory;
  83339. }
  83340. $sourceIncludeFiles = $xmlConfiguration->source()->includeFiles();
  83341. $sourceExcludeDirectories = $xmlConfiguration->source()->excludeDirectories();
  83342. $sourceExcludeFiles = $xmlConfiguration->source()->excludeFiles();
  83343. }
  83344. $useBaseline = null;
  83345. $generateBaseline = null;
  83346. if (!$cliConfiguration->hasGenerateBaseline()) {
  83347. if ($cliConfiguration->hasUseBaseline()) {
  83348. $useBaseline = $cliConfiguration->useBaseline();
  83349. } elseif ($xmlConfiguration->source()->hasBaseline()) {
  83350. $useBaseline = $xmlConfiguration->source()->baseline();
  83351. }
  83352. } else {
  83353. $generateBaseline = $cliConfiguration->generateBaseline();
  83354. }
  83355. assert($useBaseline !== '');
  83356. assert($generateBaseline !== '');
  83357. return new \PHPUnit\TextUI\Configuration\Configuration($cliConfiguration->arguments(), $configurationFile, $bootstrap, $cacheResult, $cacheDirectory, $coverageCacheDirectory, new \PHPUnit\TextUI\Configuration\Source($useBaseline, $cliConfiguration->ignoreBaseline(), \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::fromArray($sourceIncludeDirectories), $sourceIncludeFiles, $sourceExcludeDirectories, $sourceExcludeFiles, $xmlConfiguration->source()->restrictDeprecations(), $xmlConfiguration->source()->restrictNotices(), $xmlConfiguration->source()->restrictWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfPhpDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfErrors(), $xmlConfiguration->source()->ignoreSuppressionOfNotices(), $xmlConfiguration->source()->ignoreSuppressionOfPhpNotices(), $xmlConfiguration->source()->ignoreSuppressionOfWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfPhpWarnings()), $testResultCacheFile, $coverageClover, $coverageCobertura, $coverageCrap4j, $coverageCrap4jThreshold, $coverageHtml, $coverageHtmlLowUpperBound, $coverageHtmlHighLowerBound, $coverageHtmlColorSuccessLow, $coverageHtmlColorSuccessMedium, $coverageHtmlColorSuccessHigh, $coverageHtmlColorWarning, $coverageHtmlColorDanger, $coverageHtmlCustomCssFile, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $xmlConfiguration->codeCoverage()->ignoreDeprecatedCodeUnits(), $disableCodeCoverageIgnore, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $outputToStandardErrorStream, $columns, $noExtensions, $pharExtensionDirectory, $extensionBootstrappers, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $colors, $processIsolation, $enforceTimeLimit, $defaultTimeLimit, $timeoutForSmallTests, $timeoutForMediumTests, $timeoutForLargeTests, $reportUselessTests, $strictCoverage, $disallowTestOutput, $displayDetailsOnIncompleteTests, $displayDetailsOnSkippedTests, $displayDetailsOnTestsThatTriggerDeprecations, $displayDetailsOnPhpunitDeprecations, $displayDetailsOnTestsThatTriggerErrors, $displayDetailsOnTestsThatTriggerNotices, $displayDetailsOnTestsThatTriggerWarnings, $reverseDefectList, $requireCoverageMetadata, $registerMockObjectsFromTestArgumentsRecursively, $noProgress, $noResults, $noOutput, $executionOrder, $executionOrderDefects, $resolveDependencies, $logfileTeamcity, $logfileJunit, $logfileTestdoxHtml, $logfileTestdoxText, $logEventsText, $logEventsVerboseText, $teamCityOutput, $testDoxOutput, $testsCovering, $testsUsing, $filter, $groups, $excludeGroups, $randomOrderSeed, $includeUncoveredFiles, $xmlConfiguration->testSuite(), $includeTestSuite, $excludeTestSuite, $xmlConfiguration->phpunit()->hasDefaultTestSuite() ? $xmlConfiguration->phpunit()->defaultTestSuite() : null, $testSuffixes, new \PHPUnit\TextUI\Configuration\Php(\PHPUnit\TextUI\Configuration\DirectoryCollection::fromArray($includePaths), \PHPUnit\TextUI\Configuration\IniSettingCollection::fromArray($iniSettings), $xmlConfiguration->php()->constants(), $xmlConfiguration->php()->globalVariables(), $xmlConfiguration->php()->envVariables(), $xmlConfiguration->php()->postVariables(), $xmlConfiguration->php()->getVariables(), $xmlConfiguration->php()->cookieVariables(), $xmlConfiguration->php()->serverVariables(), $xmlConfiguration->php()->filesVariables(), $xmlConfiguration->php()->requestVariables()), $xmlConfiguration->phpunit()->controlGarbageCollector(), $xmlConfiguration->phpunit()->numberOfTestsBeforeGarbageCollection(), $generateBaseline, $cliConfiguration->debug());
  83358. }
  83359. }
  83360. <?php
  83361. declare (strict_types=1);
  83362. /*
  83363. * This file is part of PHPUnit.
  83364. *
  83365. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83366. *
  83367. * For the full copyright and license information, please view the LICENSE
  83368. * file that was distributed with this source code.
  83369. */
  83370. namespace PHPUnit\TextUI\Configuration;
  83371. use const PATH_SEPARATOR;
  83372. use function constant;
  83373. use function define;
  83374. use function defined;
  83375. use function getenv;
  83376. use function implode;
  83377. use function ini_get;
  83378. use function ini_set;
  83379. use function putenv;
  83380. /**
  83381. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83382. *
  83383. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  83384. */
  83385. final class PhpHandler
  83386. {
  83387. public function handle(\PHPUnit\TextUI\Configuration\Php $configuration): void
  83388. {
  83389. $this->handleIncludePaths($configuration->includePaths());
  83390. $this->handleIniSettings($configuration->iniSettings());
  83391. $this->handleConstants($configuration->constants());
  83392. $this->handleGlobalVariables($configuration->globalVariables());
  83393. $this->handleServerVariables($configuration->serverVariables());
  83394. $this->handleEnvVariables($configuration->envVariables());
  83395. $this->handleVariables('_POST', $configuration->postVariables());
  83396. $this->handleVariables('_GET', $configuration->getVariables());
  83397. $this->handleVariables('_COOKIE', $configuration->cookieVariables());
  83398. $this->handleVariables('_FILES', $configuration->filesVariables());
  83399. $this->handleVariables('_REQUEST', $configuration->requestVariables());
  83400. }
  83401. private function handleIncludePaths(\PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths): void
  83402. {
  83403. if (!$includePaths->isEmpty()) {
  83404. $includePathsAsStrings = [];
  83405. foreach ($includePaths as $includePath) {
  83406. $includePathsAsStrings[] = $includePath->path();
  83407. }
  83408. ini_set('include_path', implode(PATH_SEPARATOR, $includePathsAsStrings) . PATH_SEPARATOR . ini_get('include_path'));
  83409. }
  83410. }
  83411. private function handleIniSettings(\PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings): void
  83412. {
  83413. foreach ($iniSettings as $iniSetting) {
  83414. $value = $iniSetting->value();
  83415. if (defined($value)) {
  83416. $value = (string) constant($value);
  83417. }
  83418. ini_set($iniSetting->name(), $value);
  83419. }
  83420. }
  83421. private function handleConstants(\PHPUnit\TextUI\Configuration\ConstantCollection $constants): void
  83422. {
  83423. foreach ($constants as $constant) {
  83424. if (!defined($constant->name())) {
  83425. define($constant->name(), $constant->value());
  83426. }
  83427. }
  83428. }
  83429. private function handleGlobalVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
  83430. {
  83431. foreach ($variables as $variable) {
  83432. $GLOBALS[$variable->name()] = $variable->value();
  83433. }
  83434. }
  83435. private function handleServerVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
  83436. {
  83437. foreach ($variables as $variable) {
  83438. $_SERVER[$variable->name()] = $variable->value();
  83439. }
  83440. }
  83441. private function handleVariables(string $target, \PHPUnit\TextUI\Configuration\VariableCollection $variables): void
  83442. {
  83443. foreach ($variables as $variable) {
  83444. $GLOBALS[$target][$variable->name()] = $variable->value();
  83445. }
  83446. }
  83447. private function handleEnvVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
  83448. {
  83449. foreach ($variables as $variable) {
  83450. $name = $variable->name();
  83451. $value = $variable->value();
  83452. $force = $variable->force();
  83453. if ($force || getenv($name) === \false) {
  83454. putenv("{$name}={$value}");
  83455. }
  83456. $value = getenv($name);
  83457. if ($force || !isset($_ENV[$name])) {
  83458. $_ENV[$name] = $value;
  83459. }
  83460. }
  83461. }
  83462. }
  83463. <?php
  83464. declare (strict_types=1);
  83465. /*
  83466. * This file is part of PHPUnit.
  83467. *
  83468. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83469. *
  83470. * For the full copyright and license information, please view the LICENSE
  83471. * file that was distributed with this source code.
  83472. */
  83473. namespace PHPUnit\TextUI\Configuration;
  83474. use function assert;
  83475. use function file_get_contents;
  83476. use function file_put_contents;
  83477. use function serialize;
  83478. use function unserialize;
  83479. use PHPUnit\Event\Facade as EventFacade;
  83480. use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
  83481. use PHPUnit\TextUI\CliArguments\Exception;
  83482. use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
  83483. use PHPUnit\Util\VersionComparisonOperator;
  83484. /**
  83485. * CLI options and XML configuration are static within a single PHPUnit process.
  83486. * It is therefore okay to use a Singleton registry here.
  83487. *
  83488. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83489. *
  83490. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  83491. */
  83492. final class Registry
  83493. {
  83494. private static ?\PHPUnit\TextUI\Configuration\Configuration $instance = null;
  83495. public static function saveTo(string $path): bool
  83496. {
  83497. $result = file_put_contents($path, serialize(self::get()));
  83498. if ($result) {
  83499. return \true;
  83500. }
  83501. // @codeCoverageIgnoreStart
  83502. return \false;
  83503. // @codeCoverageIgnoreEnd
  83504. }
  83505. /**
  83506. * This method is used by the "run test(s) in separate process" templates.
  83507. *
  83508. * @noinspection PhpUnused
  83509. *
  83510. * @codeCoverageIgnore
  83511. */
  83512. public static function loadFrom(string $path): void
  83513. {
  83514. self::$instance = unserialize(file_get_contents($path), ['allowed_classes' => [\PHPUnit\TextUI\Configuration\Configuration::class, \PHPUnit\TextUI\Configuration\Php::class, \PHPUnit\TextUI\Configuration\ConstantCollection::class, \PHPUnit\TextUI\Configuration\Constant::class, \PHPUnit\TextUI\Configuration\IniSettingCollection::class, \PHPUnit\TextUI\Configuration\IniSetting::class, \PHPUnit\TextUI\Configuration\VariableCollection::class, \PHPUnit\TextUI\Configuration\Variable::class, \PHPUnit\TextUI\Configuration\DirectoryCollection::class, \PHPUnit\TextUI\Configuration\Directory::class, \PHPUnit\TextUI\Configuration\FileCollection::class, \PHPUnit\TextUI\Configuration\File::class, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::class, \PHPUnit\TextUI\Configuration\FilterDirectory::class, \PHPUnit\TextUI\Configuration\TestDirectoryCollection::class, \PHPUnit\TextUI\Configuration\TestDirectory::class, \PHPUnit\TextUI\Configuration\TestFileCollection::class, \PHPUnit\TextUI\Configuration\TestFile::class, \PHPUnit\TextUI\Configuration\TestSuiteCollection::class, \PHPUnit\TextUI\Configuration\TestSuite::class, VersionComparisonOperator::class, \PHPUnit\TextUI\Configuration\Source::class]]);
  83515. }
  83516. public static function get(): \PHPUnit\TextUI\Configuration\Configuration
  83517. {
  83518. assert(self::$instance instanceof \PHPUnit\TextUI\Configuration\Configuration);
  83519. return self::$instance;
  83520. }
  83521. /**
  83522. * @throws \PHPUnit\TextUI\XmlConfiguration\Exception
  83523. * @throws Exception
  83524. * @throws NoCustomCssFileException
  83525. */
  83526. public static function init(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): \PHPUnit\TextUI\Configuration\Configuration
  83527. {
  83528. self::$instance = (new \PHPUnit\TextUI\Configuration\Merger())->merge($cliConfiguration, $xmlConfiguration);
  83529. EventFacade::emitter()->testRunnerConfigured(self::$instance);
  83530. return self::$instance;
  83531. }
  83532. }
  83533. <?php
  83534. declare (strict_types=1);
  83535. /*
  83536. * This file is part of PHPUnit.
  83537. *
  83538. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83539. *
  83540. * For the full copyright and license information, please view the LICENSE
  83541. * file that was distributed with this source code.
  83542. */
  83543. namespace PHPUnit\TextUI\Configuration;
  83544. /**
  83545. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83546. *
  83547. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  83548. */
  83549. final class SourceFilter
  83550. {
  83551. public function includes(\PHPUnit\TextUI\Configuration\Source $source, string $path): bool
  83552. {
  83553. $files = (new \PHPUnit\TextUI\Configuration\SourceMapper())->map($source);
  83554. return isset($files[$path]);
  83555. }
  83556. }
  83557. <?php
  83558. declare (strict_types=1);
  83559. /*
  83560. * This file is part of PHPUnit.
  83561. *
  83562. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83563. *
  83564. * For the full copyright and license information, please view the LICENSE
  83565. * file that was distributed with this source code.
  83566. */
  83567. namespace PHPUnit\TextUI\Configuration;
  83568. use function realpath;
  83569. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  83570. use SplObjectStorage;
  83571. /**
  83572. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83573. *
  83574. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  83575. */
  83576. final class SourceMapper
  83577. {
  83578. /**
  83579. * @psalm-var SplObjectStorage<Source, array<non-empty-string, true>>
  83580. */
  83581. private static ?SplObjectStorage $files = null;
  83582. /**
  83583. * @psalm-return array<non-empty-string, true>
  83584. */
  83585. public function map(\PHPUnit\TextUI\Configuration\Source $source): array
  83586. {
  83587. if (self::$files === null) {
  83588. self::$files = new SplObjectStorage();
  83589. }
  83590. if (isset(self::$files[$source])) {
  83591. return self::$files[$source];
  83592. }
  83593. $files = [];
  83594. foreach ($source->includeDirectories() as $directory) {
  83595. foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
  83596. $file = realpath($file);
  83597. if (!$file) {
  83598. continue;
  83599. }
  83600. $files[$file] = \true;
  83601. }
  83602. }
  83603. foreach ($source->includeFiles() as $file) {
  83604. $file = realpath($file->path());
  83605. if (!$file) {
  83606. continue;
  83607. }
  83608. $files[$file] = \true;
  83609. }
  83610. foreach ($source->excludeDirectories() as $directory) {
  83611. foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
  83612. $file = realpath($file);
  83613. if (!$file) {
  83614. continue;
  83615. }
  83616. if (!isset($files[$file])) {
  83617. continue;
  83618. }
  83619. unset($files[$file]);
  83620. }
  83621. }
  83622. foreach ($source->excludeFiles() as $file) {
  83623. $file = realpath($file->path());
  83624. if (!$file) {
  83625. continue;
  83626. }
  83627. if (!isset($files[$file])) {
  83628. continue;
  83629. }
  83630. unset($files[$file]);
  83631. }
  83632. self::$files[$source] = $files;
  83633. return $files;
  83634. }
  83635. }
  83636. <?php
  83637. declare (strict_types=1);
  83638. /*
  83639. * This file is part of PHPUnit.
  83640. *
  83641. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83642. *
  83643. * For the full copyright and license information, please view the LICENSE
  83644. * file that was distributed with this source code.
  83645. */
  83646. namespace PHPUnit\TextUI\Configuration;
  83647. use const PHP_EOL;
  83648. use function assert;
  83649. use function count;
  83650. use function is_dir;
  83651. use function is_file;
  83652. use function realpath;
  83653. use function str_ends_with;
  83654. use PHPUnit\Event\Facade as EventFacade;
  83655. use PHPUnit\Exception;
  83656. use PHPUnit\Framework\TestSuite;
  83657. use PHPUnit\Runner\TestSuiteLoader;
  83658. use PHPUnit\TextUI\RuntimeException;
  83659. use PHPUnit\TextUI\TestDirectoryNotFoundException;
  83660. use PHPUnit\TextUI\TestFileNotFoundException;
  83661. use PHPUnit\TextUI\XmlConfiguration\TestSuiteMapper;
  83662. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  83663. /**
  83664. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83665. *
  83666. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  83667. */
  83668. final class TestSuiteBuilder
  83669. {
  83670. /**
  83671. * @throws \PHPUnit\Framework\Exception
  83672. * @throws RuntimeException
  83673. * @throws TestDirectoryNotFoundException
  83674. * @throws TestFileNotFoundException
  83675. */
  83676. public function build(\PHPUnit\TextUI\Configuration\Configuration $configuration): TestSuite
  83677. {
  83678. if ($configuration->hasCliArguments()) {
  83679. $arguments = [];
  83680. foreach ($configuration->cliArguments() as $cliArgument) {
  83681. $argument = realpath($cliArgument);
  83682. if (!$argument) {
  83683. throw new TestFileNotFoundException($cliArgument);
  83684. }
  83685. $arguments[] = $argument;
  83686. }
  83687. if (count($arguments) === 1) {
  83688. $testSuite = $this->testSuiteFromPath($arguments[0], $configuration->testSuffixes());
  83689. } else {
  83690. $testSuite = $this->testSuiteFromPathList($arguments, $configuration->testSuffixes());
  83691. }
  83692. }
  83693. if (!isset($testSuite)) {
  83694. $xmlConfigurationFile = $configuration->hasConfigurationFile() ? $configuration->configurationFile() : 'Root Test Suite';
  83695. assert(!empty($xmlConfigurationFile));
  83696. $testSuite = (new TestSuiteMapper())->map($xmlConfigurationFile, $configuration->testSuite(), $configuration->includeTestSuite(), $configuration->excludeTestSuite());
  83697. }
  83698. EventFacade::emitter()->testSuiteLoaded(\PHPUnit\Event\TestSuite\TestSuiteBuilder::from($testSuite));
  83699. return $testSuite;
  83700. }
  83701. /**
  83702. * @psalm-param non-empty-string $path
  83703. * @psalm-param list<non-empty-string> $suffixes
  83704. * @psalm-param ?TestSuite $suite
  83705. *
  83706. * @throws \PHPUnit\Framework\Exception
  83707. */
  83708. private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $suite = null): TestSuite
  83709. {
  83710. if (str_ends_with($path, '.phpt') && is_file($path)) {
  83711. $suite = $suite ?: TestSuite::empty($path);
  83712. $suite->addTestFile($path);
  83713. return $suite;
  83714. }
  83715. if (is_dir($path)) {
  83716. $files = (new FileIteratorFacade())->getFilesAsArray($path, $suffixes);
  83717. $suite = $suite ?: TestSuite::empty('CLI Arguments');
  83718. $suite->addTestFiles($files);
  83719. return $suite;
  83720. }
  83721. try {
  83722. $testClass = (new TestSuiteLoader())->load($path);
  83723. } catch (Exception $e) {
  83724. print $e->getMessage() . PHP_EOL;
  83725. exit(1);
  83726. }
  83727. if (!$suite) {
  83728. return TestSuite::fromClassReflector($testClass);
  83729. }
  83730. $suite->addTestSuite($testClass);
  83731. return $suite;
  83732. }
  83733. /**
  83734. * @psalm-param list<non-empty-string> $paths
  83735. * @psalm-param list<non-empty-string> $suffixes
  83736. *
  83737. * @throws \PHPUnit\Framework\Exception
  83738. */
  83739. private function testSuiteFromPathList(array $paths, array $suffixes): TestSuite
  83740. {
  83741. $suite = TestSuite::empty('CLI Arguments');
  83742. foreach ($paths as $path) {
  83743. $this->testSuiteFromPath($path, $suffixes, $suite);
  83744. }
  83745. return $suite;
  83746. }
  83747. }
  83748. <?php
  83749. declare (strict_types=1);
  83750. /*
  83751. * This file is part of PHPUnit.
  83752. *
  83753. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83754. *
  83755. * For the full copyright and license information, please view the LICENSE
  83756. * file that was distributed with this source code.
  83757. */
  83758. namespace PHPUnit\TextUI\Configuration;
  83759. /**
  83760. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83761. *
  83762. * @psalm-immutable
  83763. */
  83764. final class Constant
  83765. {
  83766. private readonly string $name;
  83767. private readonly bool|string $value;
  83768. public function __construct(string $name, bool|string $value)
  83769. {
  83770. $this->name = $name;
  83771. $this->value = $value;
  83772. }
  83773. public function name(): string
  83774. {
  83775. return $this->name;
  83776. }
  83777. public function value(): bool|string
  83778. {
  83779. return $this->value;
  83780. }
  83781. }
  83782. <?php
  83783. declare (strict_types=1);
  83784. /*
  83785. * This file is part of PHPUnit.
  83786. *
  83787. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83788. *
  83789. * For the full copyright and license information, please view the LICENSE
  83790. * file that was distributed with this source code.
  83791. */
  83792. namespace PHPUnit\TextUI\Configuration;
  83793. use function count;
  83794. use Countable;
  83795. use IteratorAggregate;
  83796. /**
  83797. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83798. *
  83799. * @psalm-immutable
  83800. *
  83801. * @template-implements IteratorAggregate<int, Constant>
  83802. */
  83803. final class ConstantCollection implements Countable, IteratorAggregate
  83804. {
  83805. /**
  83806. * @psalm-var list<Constant>
  83807. */
  83808. private readonly array $constants;
  83809. /**
  83810. * @psalm-param list<Constant> $constants
  83811. */
  83812. public static function fromArray(array $constants): self
  83813. {
  83814. return new self(...$constants);
  83815. }
  83816. private function __construct(\PHPUnit\TextUI\Configuration\Constant ...$constants)
  83817. {
  83818. $this->constants = $constants;
  83819. }
  83820. /**
  83821. * @psalm-return list<Constant>
  83822. */
  83823. public function asArray(): array
  83824. {
  83825. return $this->constants;
  83826. }
  83827. public function count(): int
  83828. {
  83829. return count($this->constants);
  83830. }
  83831. public function getIterator(): \PHPUnit\TextUI\Configuration\ConstantCollectionIterator
  83832. {
  83833. return new \PHPUnit\TextUI\Configuration\ConstantCollectionIterator($this);
  83834. }
  83835. }
  83836. <?php
  83837. declare (strict_types=1);
  83838. /*
  83839. * This file is part of PHPUnit.
  83840. *
  83841. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83842. *
  83843. * For the full copyright and license information, please view the LICENSE
  83844. * file that was distributed with this source code.
  83845. */
  83846. namespace PHPUnit\TextUI\Configuration;
  83847. use function count;
  83848. use function iterator_count;
  83849. use Countable;
  83850. use Iterator;
  83851. /**
  83852. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83853. *
  83854. * @template-implements Iterator<int, Constant>
  83855. */
  83856. final class ConstantCollectionIterator implements Countable, Iterator
  83857. {
  83858. /**
  83859. * @psalm-var list<Constant>
  83860. */
  83861. private readonly array $constants;
  83862. private int $position = 0;
  83863. public function __construct(\PHPUnit\TextUI\Configuration\ConstantCollection $constants)
  83864. {
  83865. $this->constants = $constants->asArray();
  83866. }
  83867. public function count(): int
  83868. {
  83869. return iterator_count($this);
  83870. }
  83871. public function rewind(): void
  83872. {
  83873. $this->position = 0;
  83874. }
  83875. public function valid(): bool
  83876. {
  83877. return $this->position < count($this->constants);
  83878. }
  83879. public function key(): int
  83880. {
  83881. return $this->position;
  83882. }
  83883. public function current(): \PHPUnit\TextUI\Configuration\Constant
  83884. {
  83885. return $this->constants[$this->position];
  83886. }
  83887. public function next(): void
  83888. {
  83889. $this->position++;
  83890. }
  83891. }
  83892. <?php
  83893. declare (strict_types=1);
  83894. /*
  83895. * This file is part of PHPUnit.
  83896. *
  83897. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83898. *
  83899. * For the full copyright and license information, please view the LICENSE
  83900. * file that was distributed with this source code.
  83901. */
  83902. namespace PHPUnit\TextUI\Configuration;
  83903. /**
  83904. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83905. *
  83906. * @psalm-immutable
  83907. */
  83908. final class Directory
  83909. {
  83910. private readonly string $path;
  83911. public function __construct(string $path)
  83912. {
  83913. $this->path = $path;
  83914. }
  83915. public function path(): string
  83916. {
  83917. return $this->path;
  83918. }
  83919. }
  83920. <?php
  83921. declare (strict_types=1);
  83922. /*
  83923. * This file is part of PHPUnit.
  83924. *
  83925. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83926. *
  83927. * For the full copyright and license information, please view the LICENSE
  83928. * file that was distributed with this source code.
  83929. */
  83930. namespace PHPUnit\TextUI\Configuration;
  83931. use function count;
  83932. use Countable;
  83933. use IteratorAggregate;
  83934. /**
  83935. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83936. *
  83937. * @psalm-immutable
  83938. *
  83939. * @template-implements IteratorAggregate<int, Directory>
  83940. */
  83941. final class DirectoryCollection implements Countable, IteratorAggregate
  83942. {
  83943. /**
  83944. * @psalm-var list<Directory>
  83945. */
  83946. private readonly array $directories;
  83947. /**
  83948. * @psalm-param list<Directory> $directories
  83949. */
  83950. public static function fromArray(array $directories): self
  83951. {
  83952. return new self(...$directories);
  83953. }
  83954. private function __construct(\PHPUnit\TextUI\Configuration\Directory ...$directories)
  83955. {
  83956. $this->directories = $directories;
  83957. }
  83958. /**
  83959. * @psalm-return list<Directory>
  83960. */
  83961. public function asArray(): array
  83962. {
  83963. return $this->directories;
  83964. }
  83965. public function count(): int
  83966. {
  83967. return count($this->directories);
  83968. }
  83969. public function getIterator(): \PHPUnit\TextUI\Configuration\DirectoryCollectionIterator
  83970. {
  83971. return new \PHPUnit\TextUI\Configuration\DirectoryCollectionIterator($this);
  83972. }
  83973. public function isEmpty(): bool
  83974. {
  83975. return $this->count() === 0;
  83976. }
  83977. }
  83978. <?php
  83979. declare (strict_types=1);
  83980. /*
  83981. * This file is part of PHPUnit.
  83982. *
  83983. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  83984. *
  83985. * For the full copyright and license information, please view the LICENSE
  83986. * file that was distributed with this source code.
  83987. */
  83988. namespace PHPUnit\TextUI\Configuration;
  83989. use function count;
  83990. use function iterator_count;
  83991. use Countable;
  83992. use Iterator;
  83993. /**
  83994. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  83995. *
  83996. * @template-implements Iterator<int, Directory>
  83997. */
  83998. final class DirectoryCollectionIterator implements Countable, Iterator
  83999. {
  84000. /**
  84001. * @psalm-var list<Directory>
  84002. */
  84003. private readonly array $directories;
  84004. private int $position = 0;
  84005. public function __construct(\PHPUnit\TextUI\Configuration\DirectoryCollection $directories)
  84006. {
  84007. $this->directories = $directories->asArray();
  84008. }
  84009. public function count(): int
  84010. {
  84011. return iterator_count($this);
  84012. }
  84013. public function rewind(): void
  84014. {
  84015. $this->position = 0;
  84016. }
  84017. public function valid(): bool
  84018. {
  84019. return $this->position < count($this->directories);
  84020. }
  84021. public function key(): int
  84022. {
  84023. return $this->position;
  84024. }
  84025. public function current(): \PHPUnit\TextUI\Configuration\Directory
  84026. {
  84027. return $this->directories[$this->position];
  84028. }
  84029. public function next(): void
  84030. {
  84031. $this->position++;
  84032. }
  84033. }
  84034. <?php
  84035. declare (strict_types=1);
  84036. /*
  84037. * This file is part of PHPUnit.
  84038. *
  84039. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84040. *
  84041. * For the full copyright and license information, please view the LICENSE
  84042. * file that was distributed with this source code.
  84043. */
  84044. namespace PHPUnit\TextUI\Configuration;
  84045. /**
  84046. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84047. *
  84048. * @psalm-immutable
  84049. */
  84050. final class ExtensionBootstrap
  84051. {
  84052. /**
  84053. * @psalm-var class-string
  84054. */
  84055. private readonly string $className;
  84056. /**
  84057. * @psalm-var array<string,string>
  84058. */
  84059. private readonly array $parameters;
  84060. /**
  84061. * @psalm-param class-string $className
  84062. * @psalm-param array<string,string> $parameters
  84063. */
  84064. public function __construct(string $className, array $parameters)
  84065. {
  84066. $this->className = $className;
  84067. $this->parameters = $parameters;
  84068. }
  84069. /**
  84070. * @psalm-return class-string
  84071. */
  84072. public function className(): string
  84073. {
  84074. return $this->className;
  84075. }
  84076. /**
  84077. * @psalm-return array<string,string>
  84078. */
  84079. public function parameters(): array
  84080. {
  84081. return $this->parameters;
  84082. }
  84083. }
  84084. <?php
  84085. declare (strict_types=1);
  84086. /*
  84087. * This file is part of PHPUnit.
  84088. *
  84089. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84090. *
  84091. * For the full copyright and license information, please view the LICENSE
  84092. * file that was distributed with this source code.
  84093. */
  84094. namespace PHPUnit\TextUI\Configuration;
  84095. use IteratorAggregate;
  84096. /**
  84097. * @template-implements IteratorAggregate<int, ExtensionBootstrap>
  84098. *
  84099. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84100. *
  84101. * @psalm-immutable
  84102. */
  84103. final class ExtensionBootstrapCollection implements IteratorAggregate
  84104. {
  84105. /**
  84106. * @psalm-var list<ExtensionBootstrap>
  84107. */
  84108. private readonly array $extensionBootstraps;
  84109. /**
  84110. * @psalm-param list<ExtensionBootstrap> $extensionBootstraps
  84111. */
  84112. public static function fromArray(array $extensionBootstraps): self
  84113. {
  84114. return new self(...$extensionBootstraps);
  84115. }
  84116. private function __construct(\PHPUnit\TextUI\Configuration\ExtensionBootstrap ...$extensionBootstraps)
  84117. {
  84118. $this->extensionBootstraps = $extensionBootstraps;
  84119. }
  84120. /**
  84121. * @psalm-return list<ExtensionBootstrap>
  84122. */
  84123. public function asArray(): array
  84124. {
  84125. return $this->extensionBootstraps;
  84126. }
  84127. public function getIterator(): \PHPUnit\TextUI\Configuration\ExtensionBootstrapCollectionIterator
  84128. {
  84129. return new \PHPUnit\TextUI\Configuration\ExtensionBootstrapCollectionIterator($this);
  84130. }
  84131. }
  84132. <?php
  84133. declare (strict_types=1);
  84134. /*
  84135. * This file is part of PHPUnit.
  84136. *
  84137. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84138. *
  84139. * For the full copyright and license information, please view the LICENSE
  84140. * file that was distributed with this source code.
  84141. */
  84142. namespace PHPUnit\TextUI\Configuration;
  84143. use function count;
  84144. use function iterator_count;
  84145. use Countable;
  84146. use Iterator;
  84147. /**
  84148. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84149. *
  84150. * @template-implements Iterator<int, ExtensionBootstrap>
  84151. */
  84152. final class ExtensionBootstrapCollectionIterator implements Countable, Iterator
  84153. {
  84154. /**
  84155. * @psalm-var list<ExtensionBootstrap>
  84156. */
  84157. private readonly array $extensionBootstraps;
  84158. private int $position = 0;
  84159. public function __construct(\PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection $extensionBootstraps)
  84160. {
  84161. $this->extensionBootstraps = $extensionBootstraps->asArray();
  84162. }
  84163. public function count(): int
  84164. {
  84165. return iterator_count($this);
  84166. }
  84167. public function rewind(): void
  84168. {
  84169. $this->position = 0;
  84170. }
  84171. public function valid(): bool
  84172. {
  84173. return $this->position < count($this->extensionBootstraps);
  84174. }
  84175. public function key(): int
  84176. {
  84177. return $this->position;
  84178. }
  84179. public function current(): \PHPUnit\TextUI\Configuration\ExtensionBootstrap
  84180. {
  84181. return $this->extensionBootstraps[$this->position];
  84182. }
  84183. public function next(): void
  84184. {
  84185. $this->position++;
  84186. }
  84187. }
  84188. <?php
  84189. declare (strict_types=1);
  84190. /*
  84191. * This file is part of PHPUnit.
  84192. *
  84193. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84194. *
  84195. * For the full copyright and license information, please view the LICENSE
  84196. * file that was distributed with this source code.
  84197. */
  84198. namespace PHPUnit\TextUI\Configuration;
  84199. /**
  84200. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84201. *
  84202. * @psalm-immutable
  84203. */
  84204. final class File
  84205. {
  84206. /**
  84207. * @psalm-var non-empty-string
  84208. */
  84209. private readonly string $path;
  84210. /**
  84211. * @psalm-param non-empty-string $path
  84212. */
  84213. public function __construct(string $path)
  84214. {
  84215. $this->path = $path;
  84216. }
  84217. /**
  84218. * @psalm-return non-empty-string
  84219. */
  84220. public function path(): string
  84221. {
  84222. return $this->path;
  84223. }
  84224. }
  84225. <?php
  84226. declare (strict_types=1);
  84227. /*
  84228. * This file is part of PHPUnit.
  84229. *
  84230. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84231. *
  84232. * For the full copyright and license information, please view the LICENSE
  84233. * file that was distributed with this source code.
  84234. */
  84235. namespace PHPUnit\TextUI\Configuration;
  84236. use function count;
  84237. use Countable;
  84238. use IteratorAggregate;
  84239. /**
  84240. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84241. *
  84242. * @psalm-immutable
  84243. *
  84244. * @template-implements IteratorAggregate<int, File>
  84245. */
  84246. final class FileCollection implements Countable, IteratorAggregate
  84247. {
  84248. /**
  84249. * @psalm-var list<File>
  84250. */
  84251. private readonly array $files;
  84252. /**
  84253. * @psalm-param list<File> $files
  84254. */
  84255. public static function fromArray(array $files): self
  84256. {
  84257. return new self(...$files);
  84258. }
  84259. private function __construct(\PHPUnit\TextUI\Configuration\File ...$files)
  84260. {
  84261. $this->files = $files;
  84262. }
  84263. /**
  84264. * @psalm-return list<File>
  84265. */
  84266. public function asArray(): array
  84267. {
  84268. return $this->files;
  84269. }
  84270. public function count(): int
  84271. {
  84272. return count($this->files);
  84273. }
  84274. public function notEmpty(): bool
  84275. {
  84276. return !empty($this->files);
  84277. }
  84278. public function getIterator(): \PHPUnit\TextUI\Configuration\FileCollectionIterator
  84279. {
  84280. return new \PHPUnit\TextUI\Configuration\FileCollectionIterator($this);
  84281. }
  84282. }
  84283. <?php
  84284. declare (strict_types=1);
  84285. /*
  84286. * This file is part of PHPUnit.
  84287. *
  84288. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84289. *
  84290. * For the full copyright and license information, please view the LICENSE
  84291. * file that was distributed with this source code.
  84292. */
  84293. namespace PHPUnit\TextUI\Configuration;
  84294. use function count;
  84295. use function iterator_count;
  84296. use Countable;
  84297. use Iterator;
  84298. /**
  84299. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84300. *
  84301. * @template-implements Iterator<int, File>
  84302. */
  84303. final class FileCollectionIterator implements Countable, Iterator
  84304. {
  84305. /**
  84306. * @psalm-var list<File>
  84307. */
  84308. private readonly array $files;
  84309. private int $position = 0;
  84310. public function __construct(\PHPUnit\TextUI\Configuration\FileCollection $files)
  84311. {
  84312. $this->files = $files->asArray();
  84313. }
  84314. public function count(): int
  84315. {
  84316. return iterator_count($this);
  84317. }
  84318. public function rewind(): void
  84319. {
  84320. $this->position = 0;
  84321. }
  84322. public function valid(): bool
  84323. {
  84324. return $this->position < count($this->files);
  84325. }
  84326. public function key(): int
  84327. {
  84328. return $this->position;
  84329. }
  84330. public function current(): \PHPUnit\TextUI\Configuration\File
  84331. {
  84332. return $this->files[$this->position];
  84333. }
  84334. public function next(): void
  84335. {
  84336. $this->position++;
  84337. }
  84338. }
  84339. <?php
  84340. declare (strict_types=1);
  84341. /*
  84342. * This file is part of PHPUnit.
  84343. *
  84344. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84345. *
  84346. * For the full copyright and license information, please view the LICENSE
  84347. * file that was distributed with this source code.
  84348. */
  84349. namespace PHPUnit\TextUI\Configuration;
  84350. /**
  84351. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84352. *
  84353. * @psalm-immutable
  84354. */
  84355. final class FilterDirectory
  84356. {
  84357. /**
  84358. * @psalm-var non-empty-string
  84359. */
  84360. private readonly string $path;
  84361. private readonly string $prefix;
  84362. private readonly string $suffix;
  84363. /**
  84364. * @psalm-param non-empty-string $path
  84365. */
  84366. public function __construct(string $path, string $prefix, string $suffix)
  84367. {
  84368. $this->path = $path;
  84369. $this->prefix = $prefix;
  84370. $this->suffix = $suffix;
  84371. }
  84372. /**
  84373. * @psalm-return non-empty-string
  84374. */
  84375. public function path(): string
  84376. {
  84377. return $this->path;
  84378. }
  84379. public function prefix(): string
  84380. {
  84381. return $this->prefix;
  84382. }
  84383. public function suffix(): string
  84384. {
  84385. return $this->suffix;
  84386. }
  84387. }
  84388. <?php
  84389. declare (strict_types=1);
  84390. /*
  84391. * This file is part of PHPUnit.
  84392. *
  84393. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84394. *
  84395. * For the full copyright and license information, please view the LICENSE
  84396. * file that was distributed with this source code.
  84397. */
  84398. namespace PHPUnit\TextUI\Configuration;
  84399. use function count;
  84400. use Countable;
  84401. use IteratorAggregate;
  84402. /**
  84403. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84404. *
  84405. * @psalm-immutable
  84406. *
  84407. * @template-implements IteratorAggregate<int, FilterDirectory>
  84408. */
  84409. final class FilterDirectoryCollection implements Countable, IteratorAggregate
  84410. {
  84411. /**
  84412. * @psalm-var list<FilterDirectory>
  84413. */
  84414. private readonly array $directories;
  84415. /**
  84416. * @psalm-param list<FilterDirectory> $directories
  84417. */
  84418. public static function fromArray(array $directories): self
  84419. {
  84420. return new self(...$directories);
  84421. }
  84422. private function __construct(\PHPUnit\TextUI\Configuration\FilterDirectory ...$directories)
  84423. {
  84424. $this->directories = $directories;
  84425. }
  84426. /**
  84427. * @psalm-return list<FilterDirectory>
  84428. */
  84429. public function asArray(): array
  84430. {
  84431. return $this->directories;
  84432. }
  84433. public function count(): int
  84434. {
  84435. return count($this->directories);
  84436. }
  84437. public function notEmpty(): bool
  84438. {
  84439. return !empty($this->directories);
  84440. }
  84441. public function getIterator(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollectionIterator
  84442. {
  84443. return new \PHPUnit\TextUI\Configuration\FilterDirectoryCollectionIterator($this);
  84444. }
  84445. }
  84446. <?php
  84447. declare (strict_types=1);
  84448. /*
  84449. * This file is part of PHPUnit.
  84450. *
  84451. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84452. *
  84453. * For the full copyright and license information, please view the LICENSE
  84454. * file that was distributed with this source code.
  84455. */
  84456. namespace PHPUnit\TextUI\Configuration;
  84457. use function count;
  84458. use function iterator_count;
  84459. use Countable;
  84460. use Iterator;
  84461. /**
  84462. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84463. *
  84464. * @template-implements Iterator<int, FilterDirectory>
  84465. */
  84466. final class FilterDirectoryCollectionIterator implements Countable, Iterator
  84467. {
  84468. /**
  84469. * @psalm-var list<FilterDirectory>
  84470. */
  84471. private readonly array $directories;
  84472. private int $position = 0;
  84473. public function __construct(\PHPUnit\TextUI\Configuration\FilterDirectoryCollection $directories)
  84474. {
  84475. $this->directories = $directories->asArray();
  84476. }
  84477. public function count(): int
  84478. {
  84479. return iterator_count($this);
  84480. }
  84481. public function rewind(): void
  84482. {
  84483. $this->position = 0;
  84484. }
  84485. public function valid(): bool
  84486. {
  84487. return $this->position < count($this->directories);
  84488. }
  84489. public function key(): int
  84490. {
  84491. return $this->position;
  84492. }
  84493. public function current(): \PHPUnit\TextUI\Configuration\FilterDirectory
  84494. {
  84495. return $this->directories[$this->position];
  84496. }
  84497. public function next(): void
  84498. {
  84499. $this->position++;
  84500. }
  84501. }
  84502. <?php
  84503. declare (strict_types=1);
  84504. /*
  84505. * This file is part of PHPUnit.
  84506. *
  84507. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84508. *
  84509. * For the full copyright and license information, please view the LICENSE
  84510. * file that was distributed with this source code.
  84511. */
  84512. namespace PHPUnit\TextUI\Configuration;
  84513. /**
  84514. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84515. *
  84516. * @psalm-immutable
  84517. */
  84518. final class Group
  84519. {
  84520. private readonly string $name;
  84521. public function __construct(string $name)
  84522. {
  84523. $this->name = $name;
  84524. }
  84525. public function name(): string
  84526. {
  84527. return $this->name;
  84528. }
  84529. }
  84530. <?php
  84531. declare (strict_types=1);
  84532. /*
  84533. * This file is part of PHPUnit.
  84534. *
  84535. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84536. *
  84537. * For the full copyright and license information, please view the LICENSE
  84538. * file that was distributed with this source code.
  84539. */
  84540. namespace PHPUnit\TextUI\Configuration;
  84541. use IteratorAggregate;
  84542. /**
  84543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84544. *
  84545. * @psalm-immutable
  84546. *
  84547. * @template-implements IteratorAggregate<int, Group>
  84548. */
  84549. final class GroupCollection implements IteratorAggregate
  84550. {
  84551. /**
  84552. * @psalm-var list<Group>
  84553. */
  84554. private readonly array $groups;
  84555. /**
  84556. * @psalm-param list<Group> $groups
  84557. */
  84558. public static function fromArray(array $groups): self
  84559. {
  84560. return new self(...$groups);
  84561. }
  84562. private function __construct(\PHPUnit\TextUI\Configuration\Group ...$groups)
  84563. {
  84564. $this->groups = $groups;
  84565. }
  84566. /**
  84567. * @psalm-return list<Group>
  84568. */
  84569. public function asArray(): array
  84570. {
  84571. return $this->groups;
  84572. }
  84573. /**
  84574. * @psalm-return list<string>
  84575. */
  84576. public function asArrayOfStrings(): array
  84577. {
  84578. $result = [];
  84579. foreach ($this->groups as $group) {
  84580. $result[] = $group->name();
  84581. }
  84582. return $result;
  84583. }
  84584. public function isEmpty(): bool
  84585. {
  84586. return empty($this->groups);
  84587. }
  84588. public function getIterator(): \PHPUnit\TextUI\Configuration\GroupCollectionIterator
  84589. {
  84590. return new \PHPUnit\TextUI\Configuration\GroupCollectionIterator($this);
  84591. }
  84592. }
  84593. <?php
  84594. declare (strict_types=1);
  84595. /*
  84596. * This file is part of PHPUnit.
  84597. *
  84598. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84599. *
  84600. * For the full copyright and license information, please view the LICENSE
  84601. * file that was distributed with this source code.
  84602. */
  84603. namespace PHPUnit\TextUI\Configuration;
  84604. use function count;
  84605. use function iterator_count;
  84606. use Countable;
  84607. use Iterator;
  84608. /**
  84609. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84610. *
  84611. * @template-implements Iterator<int, Group>
  84612. */
  84613. final class GroupCollectionIterator implements Countable, Iterator
  84614. {
  84615. /**
  84616. * @psalm-var list<Group>
  84617. */
  84618. private readonly array $groups;
  84619. private int $position = 0;
  84620. public function __construct(\PHPUnit\TextUI\Configuration\GroupCollection $groups)
  84621. {
  84622. $this->groups = $groups->asArray();
  84623. }
  84624. public function count(): int
  84625. {
  84626. return iterator_count($this);
  84627. }
  84628. public function rewind(): void
  84629. {
  84630. $this->position = 0;
  84631. }
  84632. public function valid(): bool
  84633. {
  84634. return $this->position < count($this->groups);
  84635. }
  84636. public function key(): int
  84637. {
  84638. return $this->position;
  84639. }
  84640. public function current(): \PHPUnit\TextUI\Configuration\Group
  84641. {
  84642. return $this->groups[$this->position];
  84643. }
  84644. public function next(): void
  84645. {
  84646. $this->position++;
  84647. }
  84648. }
  84649. <?php
  84650. declare (strict_types=1);
  84651. /*
  84652. * This file is part of PHPUnit.
  84653. *
  84654. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84655. *
  84656. * For the full copyright and license information, please view the LICENSE
  84657. * file that was distributed with this source code.
  84658. */
  84659. namespace PHPUnit\TextUI\Configuration;
  84660. /**
  84661. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84662. *
  84663. * @psalm-immutable
  84664. */
  84665. final class IniSetting
  84666. {
  84667. private readonly string $name;
  84668. private readonly string $value;
  84669. public function __construct(string $name, string $value)
  84670. {
  84671. $this->name = $name;
  84672. $this->value = $value;
  84673. }
  84674. public function name(): string
  84675. {
  84676. return $this->name;
  84677. }
  84678. public function value(): string
  84679. {
  84680. return $this->value;
  84681. }
  84682. }
  84683. <?php
  84684. declare (strict_types=1);
  84685. /*
  84686. * This file is part of PHPUnit.
  84687. *
  84688. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84689. *
  84690. * For the full copyright and license information, please view the LICENSE
  84691. * file that was distributed with this source code.
  84692. */
  84693. namespace PHPUnit\TextUI\Configuration;
  84694. use function count;
  84695. use Countable;
  84696. use IteratorAggregate;
  84697. /**
  84698. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84699. *
  84700. * @psalm-immutable
  84701. *
  84702. * @template-implements IteratorAggregate<int, IniSetting>
  84703. */
  84704. final class IniSettingCollection implements Countable, IteratorAggregate
  84705. {
  84706. /**
  84707. * @psalm-var list<IniSetting>
  84708. */
  84709. private readonly array $iniSettings;
  84710. /**
  84711. * @psalm-param list<IniSetting> $iniSettings
  84712. */
  84713. public static function fromArray(array $iniSettings): self
  84714. {
  84715. return new self(...$iniSettings);
  84716. }
  84717. private function __construct(\PHPUnit\TextUI\Configuration\IniSetting ...$iniSettings)
  84718. {
  84719. $this->iniSettings = $iniSettings;
  84720. }
  84721. /**
  84722. * @psalm-return list<IniSetting>
  84723. */
  84724. public function asArray(): array
  84725. {
  84726. return $this->iniSettings;
  84727. }
  84728. public function count(): int
  84729. {
  84730. return count($this->iniSettings);
  84731. }
  84732. public function getIterator(): \PHPUnit\TextUI\Configuration\IniSettingCollectionIterator
  84733. {
  84734. return new \PHPUnit\TextUI\Configuration\IniSettingCollectionIterator($this);
  84735. }
  84736. }
  84737. <?php
  84738. declare (strict_types=1);
  84739. /*
  84740. * This file is part of PHPUnit.
  84741. *
  84742. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84743. *
  84744. * For the full copyright and license information, please view the LICENSE
  84745. * file that was distributed with this source code.
  84746. */
  84747. namespace PHPUnit\TextUI\Configuration;
  84748. use function count;
  84749. use function iterator_count;
  84750. use Countable;
  84751. use Iterator;
  84752. /**
  84753. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84754. *
  84755. * @template-implements Iterator<int, IniSetting>
  84756. */
  84757. final class IniSettingCollectionIterator implements Countable, Iterator
  84758. {
  84759. /**
  84760. * @psalm-var list<IniSetting>
  84761. */
  84762. private readonly array $iniSettings;
  84763. private int $position = 0;
  84764. public function __construct(\PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings)
  84765. {
  84766. $this->iniSettings = $iniSettings->asArray();
  84767. }
  84768. public function count(): int
  84769. {
  84770. return iterator_count($this);
  84771. }
  84772. public function rewind(): void
  84773. {
  84774. $this->position = 0;
  84775. }
  84776. public function valid(): bool
  84777. {
  84778. return $this->position < count($this->iniSettings);
  84779. }
  84780. public function key(): int
  84781. {
  84782. return $this->position;
  84783. }
  84784. public function current(): \PHPUnit\TextUI\Configuration\IniSetting
  84785. {
  84786. return $this->iniSettings[$this->position];
  84787. }
  84788. public function next(): void
  84789. {
  84790. $this->position++;
  84791. }
  84792. }
  84793. <?php
  84794. declare (strict_types=1);
  84795. /*
  84796. * This file is part of PHPUnit.
  84797. *
  84798. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84799. *
  84800. * For the full copyright and license information, please view the LICENSE
  84801. * file that was distributed with this source code.
  84802. */
  84803. namespace PHPUnit\TextUI\Configuration;
  84804. /**
  84805. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84806. *
  84807. * @psalm-immutable
  84808. */
  84809. final class Php
  84810. {
  84811. private readonly \PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths;
  84812. private readonly \PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings;
  84813. private readonly \PHPUnit\TextUI\Configuration\ConstantCollection $constants;
  84814. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $globalVariables;
  84815. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $envVariables;
  84816. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $postVariables;
  84817. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $getVariables;
  84818. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $cookieVariables;
  84819. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $serverVariables;
  84820. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $filesVariables;
  84821. private readonly \PHPUnit\TextUI\Configuration\VariableCollection $requestVariables;
  84822. public function __construct(\PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths, \PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings, \PHPUnit\TextUI\Configuration\ConstantCollection $constants, \PHPUnit\TextUI\Configuration\VariableCollection $globalVariables, \PHPUnit\TextUI\Configuration\VariableCollection $envVariables, \PHPUnit\TextUI\Configuration\VariableCollection $postVariables, \PHPUnit\TextUI\Configuration\VariableCollection $getVariables, \PHPUnit\TextUI\Configuration\VariableCollection $cookieVariables, \PHPUnit\TextUI\Configuration\VariableCollection $serverVariables, \PHPUnit\TextUI\Configuration\VariableCollection $filesVariables, \PHPUnit\TextUI\Configuration\VariableCollection $requestVariables)
  84823. {
  84824. $this->includePaths = $includePaths;
  84825. $this->iniSettings = $iniSettings;
  84826. $this->constants = $constants;
  84827. $this->globalVariables = $globalVariables;
  84828. $this->envVariables = $envVariables;
  84829. $this->postVariables = $postVariables;
  84830. $this->getVariables = $getVariables;
  84831. $this->cookieVariables = $cookieVariables;
  84832. $this->serverVariables = $serverVariables;
  84833. $this->filesVariables = $filesVariables;
  84834. $this->requestVariables = $requestVariables;
  84835. }
  84836. public function includePaths(): \PHPUnit\TextUI\Configuration\DirectoryCollection
  84837. {
  84838. return $this->includePaths;
  84839. }
  84840. public function iniSettings(): \PHPUnit\TextUI\Configuration\IniSettingCollection
  84841. {
  84842. return $this->iniSettings;
  84843. }
  84844. public function constants(): \PHPUnit\TextUI\Configuration\ConstantCollection
  84845. {
  84846. return $this->constants;
  84847. }
  84848. public function globalVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84849. {
  84850. return $this->globalVariables;
  84851. }
  84852. public function envVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84853. {
  84854. return $this->envVariables;
  84855. }
  84856. public function postVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84857. {
  84858. return $this->postVariables;
  84859. }
  84860. public function getVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84861. {
  84862. return $this->getVariables;
  84863. }
  84864. public function cookieVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84865. {
  84866. return $this->cookieVariables;
  84867. }
  84868. public function serverVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84869. {
  84870. return $this->serverVariables;
  84871. }
  84872. public function filesVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84873. {
  84874. return $this->filesVariables;
  84875. }
  84876. public function requestVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
  84877. {
  84878. return $this->requestVariables;
  84879. }
  84880. }
  84881. <?php
  84882. declare (strict_types=1);
  84883. /*
  84884. * This file is part of PHPUnit.
  84885. *
  84886. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  84887. *
  84888. * For the full copyright and license information, please view the LICENSE
  84889. * file that was distributed with this source code.
  84890. */
  84891. namespace PHPUnit\TextUI\Configuration;
  84892. /**
  84893. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  84894. *
  84895. * @psalm-immutable
  84896. */
  84897. final class Source
  84898. {
  84899. /**
  84900. * @psalm-var non-empty-string
  84901. */
  84902. private readonly ?string $baseline;
  84903. private readonly bool $ignoreBaseline;
  84904. private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $includeDirectories;
  84905. private readonly \PHPUnit\TextUI\Configuration\FileCollection $includeFiles;
  84906. private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $excludeDirectories;
  84907. private readonly \PHPUnit\TextUI\Configuration\FileCollection $excludeFiles;
  84908. private readonly bool $restrictDeprecations;
  84909. private readonly bool $restrictNotices;
  84910. private readonly bool $restrictWarnings;
  84911. private readonly bool $ignoreSuppressionOfDeprecations;
  84912. private readonly bool $ignoreSuppressionOfPhpDeprecations;
  84913. private readonly bool $ignoreSuppressionOfErrors;
  84914. private readonly bool $ignoreSuppressionOfNotices;
  84915. private readonly bool $ignoreSuppressionOfPhpNotices;
  84916. private readonly bool $ignoreSuppressionOfWarnings;
  84917. private readonly bool $ignoreSuppressionOfPhpWarnings;
  84918. /**
  84919. * @psalm-param non-empty-string $baseline
  84920. */
  84921. public function __construct(?string $baseline, bool $ignoreBaseline, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $includeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $includeFiles, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $excludeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $excludeFiles, bool $restrictDeprecations, bool $restrictNotices, bool $restrictWarnings, bool $ignoreSuppressionOfDeprecations, bool $ignoreSuppressionOfPhpDeprecations, bool $ignoreSuppressionOfErrors, bool $ignoreSuppressionOfNotices, bool $ignoreSuppressionOfPhpNotices, bool $ignoreSuppressionOfWarnings, bool $ignoreSuppressionOfPhpWarnings)
  84922. {
  84923. $this->baseline = $baseline;
  84924. $this->ignoreBaseline = $ignoreBaseline;
  84925. $this->includeDirectories = $includeDirectories;
  84926. $this->includeFiles = $includeFiles;
  84927. $this->excludeDirectories = $excludeDirectories;
  84928. $this->excludeFiles = $excludeFiles;
  84929. $this->restrictDeprecations = $restrictDeprecations;
  84930. $this->restrictNotices = $restrictNotices;
  84931. $this->restrictWarnings = $restrictWarnings;
  84932. $this->ignoreSuppressionOfDeprecations = $ignoreSuppressionOfDeprecations;
  84933. $this->ignoreSuppressionOfPhpDeprecations = $ignoreSuppressionOfPhpDeprecations;
  84934. $this->ignoreSuppressionOfErrors = $ignoreSuppressionOfErrors;
  84935. $this->ignoreSuppressionOfNotices = $ignoreSuppressionOfNotices;
  84936. $this->ignoreSuppressionOfPhpNotices = $ignoreSuppressionOfPhpNotices;
  84937. $this->ignoreSuppressionOfWarnings = $ignoreSuppressionOfWarnings;
  84938. $this->ignoreSuppressionOfPhpWarnings = $ignoreSuppressionOfPhpWarnings;
  84939. }
  84940. /**
  84941. * @psalm-assert-if-true !null $this->baseline
  84942. */
  84943. public function useBaseline(): bool
  84944. {
  84945. return $this->hasBaseline() && !$this->ignoreBaseline;
  84946. }
  84947. /**
  84948. * @psalm-assert-if-true !null $this->baseline
  84949. */
  84950. public function hasBaseline(): bool
  84951. {
  84952. return $this->baseline !== null;
  84953. }
  84954. /**
  84955. * @psalm-return non-empty-string
  84956. *
  84957. * @throws NoBaselineException
  84958. */
  84959. public function baseline(): string
  84960. {
  84961. if (!$this->hasBaseline()) {
  84962. throw new \PHPUnit\TextUI\Configuration\NoBaselineException();
  84963. }
  84964. return $this->baseline;
  84965. }
  84966. public function includeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
  84967. {
  84968. return $this->includeDirectories;
  84969. }
  84970. public function includeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
  84971. {
  84972. return $this->includeFiles;
  84973. }
  84974. public function excludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
  84975. {
  84976. return $this->excludeDirectories;
  84977. }
  84978. public function excludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
  84979. {
  84980. return $this->excludeFiles;
  84981. }
  84982. public function notEmpty(): bool
  84983. {
  84984. return $this->includeDirectories->notEmpty() || $this->includeFiles->notEmpty();
  84985. }
  84986. public function restrictDeprecations(): bool
  84987. {
  84988. return $this->restrictDeprecations;
  84989. }
  84990. public function restrictNotices(): bool
  84991. {
  84992. return $this->restrictNotices;
  84993. }
  84994. public function restrictWarnings(): bool
  84995. {
  84996. return $this->restrictWarnings;
  84997. }
  84998. public function ignoreSuppressionOfDeprecations(): bool
  84999. {
  85000. return $this->ignoreSuppressionOfDeprecations;
  85001. }
  85002. public function ignoreSuppressionOfPhpDeprecations(): bool
  85003. {
  85004. return $this->ignoreSuppressionOfPhpDeprecations;
  85005. }
  85006. public function ignoreSuppressionOfErrors(): bool
  85007. {
  85008. return $this->ignoreSuppressionOfErrors;
  85009. }
  85010. public function ignoreSuppressionOfNotices(): bool
  85011. {
  85012. return $this->ignoreSuppressionOfNotices;
  85013. }
  85014. public function ignoreSuppressionOfPhpNotices(): bool
  85015. {
  85016. return $this->ignoreSuppressionOfPhpNotices;
  85017. }
  85018. public function ignoreSuppressionOfWarnings(): bool
  85019. {
  85020. return $this->ignoreSuppressionOfWarnings;
  85021. }
  85022. public function ignoreSuppressionOfPhpWarnings(): bool
  85023. {
  85024. return $this->ignoreSuppressionOfPhpWarnings;
  85025. }
  85026. }
  85027. <?php
  85028. declare (strict_types=1);
  85029. /*
  85030. * This file is part of PHPUnit.
  85031. *
  85032. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85033. *
  85034. * For the full copyright and license information, please view the LICENSE
  85035. * file that was distributed with this source code.
  85036. */
  85037. namespace PHPUnit\TextUI\Configuration;
  85038. use PHPUnit\Util\VersionComparisonOperator;
  85039. /**
  85040. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85041. *
  85042. * @psalm-immutable
  85043. */
  85044. final class TestDirectory
  85045. {
  85046. /**
  85047. * @psalm-var non-empty-string
  85048. */
  85049. private readonly string $path;
  85050. private readonly string $prefix;
  85051. private readonly string $suffix;
  85052. private readonly string $phpVersion;
  85053. private readonly VersionComparisonOperator $phpVersionOperator;
  85054. /**
  85055. * @psalm-param non-empty-string $path
  85056. */
  85057. public function __construct(string $path, string $prefix, string $suffix, string $phpVersion, VersionComparisonOperator $phpVersionOperator)
  85058. {
  85059. $this->path = $path;
  85060. $this->prefix = $prefix;
  85061. $this->suffix = $suffix;
  85062. $this->phpVersion = $phpVersion;
  85063. $this->phpVersionOperator = $phpVersionOperator;
  85064. }
  85065. /**
  85066. * @psalm-return non-empty-string
  85067. */
  85068. public function path(): string
  85069. {
  85070. return $this->path;
  85071. }
  85072. public function prefix(): string
  85073. {
  85074. return $this->prefix;
  85075. }
  85076. public function suffix(): string
  85077. {
  85078. return $this->suffix;
  85079. }
  85080. public function phpVersion(): string
  85081. {
  85082. return $this->phpVersion;
  85083. }
  85084. public function phpVersionOperator(): VersionComparisonOperator
  85085. {
  85086. return $this->phpVersionOperator;
  85087. }
  85088. }
  85089. <?php
  85090. declare (strict_types=1);
  85091. /*
  85092. * This file is part of PHPUnit.
  85093. *
  85094. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85095. *
  85096. * For the full copyright and license information, please view the LICENSE
  85097. * file that was distributed with this source code.
  85098. */
  85099. namespace PHPUnit\TextUI\Configuration;
  85100. use function count;
  85101. use Countable;
  85102. use IteratorAggregate;
  85103. /**
  85104. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85105. *
  85106. * @psalm-immutable
  85107. *
  85108. * @template-implements IteratorAggregate<int, TestDirectory>
  85109. */
  85110. final class TestDirectoryCollection implements Countable, IteratorAggregate
  85111. {
  85112. /**
  85113. * @psalm-var list<TestDirectory>
  85114. */
  85115. private readonly array $directories;
  85116. /**
  85117. * @psalm-param list<TestDirectory> $directories
  85118. */
  85119. public static function fromArray(array $directories): self
  85120. {
  85121. return new self(...$directories);
  85122. }
  85123. private function __construct(\PHPUnit\TextUI\Configuration\TestDirectory ...$directories)
  85124. {
  85125. $this->directories = $directories;
  85126. }
  85127. /**
  85128. * @psalm-return list<TestDirectory>
  85129. */
  85130. public function asArray(): array
  85131. {
  85132. return $this->directories;
  85133. }
  85134. public function count(): int
  85135. {
  85136. return count($this->directories);
  85137. }
  85138. public function getIterator(): \PHPUnit\TextUI\Configuration\TestDirectoryCollectionIterator
  85139. {
  85140. return new \PHPUnit\TextUI\Configuration\TestDirectoryCollectionIterator($this);
  85141. }
  85142. public function isEmpty(): bool
  85143. {
  85144. return $this->count() === 0;
  85145. }
  85146. }
  85147. <?php
  85148. declare (strict_types=1);
  85149. /*
  85150. * This file is part of PHPUnit.
  85151. *
  85152. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85153. *
  85154. * For the full copyright and license information, please view the LICENSE
  85155. * file that was distributed with this source code.
  85156. */
  85157. namespace PHPUnit\TextUI\Configuration;
  85158. use function count;
  85159. use function iterator_count;
  85160. use Countable;
  85161. use Iterator;
  85162. /**
  85163. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85164. *
  85165. * @template-implements Iterator<int, TestDirectory>
  85166. */
  85167. final class TestDirectoryCollectionIterator implements Countable, Iterator
  85168. {
  85169. /**
  85170. * @psalm-var list<TestDirectory>
  85171. */
  85172. private readonly array $directories;
  85173. private int $position = 0;
  85174. public function __construct(\PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories)
  85175. {
  85176. $this->directories = $directories->asArray();
  85177. }
  85178. public function count(): int
  85179. {
  85180. return iterator_count($this);
  85181. }
  85182. public function rewind(): void
  85183. {
  85184. $this->position = 0;
  85185. }
  85186. public function valid(): bool
  85187. {
  85188. return $this->position < count($this->directories);
  85189. }
  85190. public function key(): int
  85191. {
  85192. return $this->position;
  85193. }
  85194. public function current(): \PHPUnit\TextUI\Configuration\TestDirectory
  85195. {
  85196. return $this->directories[$this->position];
  85197. }
  85198. public function next(): void
  85199. {
  85200. $this->position++;
  85201. }
  85202. }
  85203. <?php
  85204. declare (strict_types=1);
  85205. /*
  85206. * This file is part of PHPUnit.
  85207. *
  85208. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85209. *
  85210. * For the full copyright and license information, please view the LICENSE
  85211. * file that was distributed with this source code.
  85212. */
  85213. namespace PHPUnit\TextUI\Configuration;
  85214. use PHPUnit\Util\VersionComparisonOperator;
  85215. /**
  85216. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85217. *
  85218. * @psalm-immutable
  85219. */
  85220. final class TestFile
  85221. {
  85222. private readonly string $path;
  85223. private readonly string $phpVersion;
  85224. private readonly VersionComparisonOperator $phpVersionOperator;
  85225. public function __construct(string $path, string $phpVersion, VersionComparisonOperator $phpVersionOperator)
  85226. {
  85227. $this->path = $path;
  85228. $this->phpVersion = $phpVersion;
  85229. $this->phpVersionOperator = $phpVersionOperator;
  85230. }
  85231. public function path(): string
  85232. {
  85233. return $this->path;
  85234. }
  85235. public function phpVersion(): string
  85236. {
  85237. return $this->phpVersion;
  85238. }
  85239. public function phpVersionOperator(): VersionComparisonOperator
  85240. {
  85241. return $this->phpVersionOperator;
  85242. }
  85243. }
  85244. <?php
  85245. declare (strict_types=1);
  85246. /*
  85247. * This file is part of PHPUnit.
  85248. *
  85249. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85250. *
  85251. * For the full copyright and license information, please view the LICENSE
  85252. * file that was distributed with this source code.
  85253. */
  85254. namespace PHPUnit\TextUI\Configuration;
  85255. use function count;
  85256. use Countable;
  85257. use IteratorAggregate;
  85258. /**
  85259. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85260. *
  85261. * @psalm-immutable
  85262. *
  85263. * @template-implements IteratorAggregate<int, TestFile>
  85264. */
  85265. final class TestFileCollection implements Countable, IteratorAggregate
  85266. {
  85267. /**
  85268. * @psalm-var list<TestFile>
  85269. */
  85270. private readonly array $files;
  85271. /**
  85272. * @psalm-param list<TestFile> $files
  85273. */
  85274. public static function fromArray(array $files): self
  85275. {
  85276. return new self(...$files);
  85277. }
  85278. private function __construct(\PHPUnit\TextUI\Configuration\TestFile ...$files)
  85279. {
  85280. $this->files = $files;
  85281. }
  85282. /**
  85283. * @psalm-return list<TestFile>
  85284. */
  85285. public function asArray(): array
  85286. {
  85287. return $this->files;
  85288. }
  85289. public function count(): int
  85290. {
  85291. return count($this->files);
  85292. }
  85293. public function getIterator(): \PHPUnit\TextUI\Configuration\TestFileCollectionIterator
  85294. {
  85295. return new \PHPUnit\TextUI\Configuration\TestFileCollectionIterator($this);
  85296. }
  85297. public function isEmpty(): bool
  85298. {
  85299. return $this->count() === 0;
  85300. }
  85301. }
  85302. <?php
  85303. declare (strict_types=1);
  85304. /*
  85305. * This file is part of PHPUnit.
  85306. *
  85307. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85308. *
  85309. * For the full copyright and license information, please view the LICENSE
  85310. * file that was distributed with this source code.
  85311. */
  85312. namespace PHPUnit\TextUI\Configuration;
  85313. use function count;
  85314. use function iterator_count;
  85315. use Countable;
  85316. use Iterator;
  85317. /**
  85318. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85319. *
  85320. * @template-implements Iterator<int, TestFile>
  85321. */
  85322. final class TestFileCollectionIterator implements Countable, Iterator
  85323. {
  85324. /**
  85325. * @psalm-var list<TestFile>
  85326. */
  85327. private readonly array $files;
  85328. private int $position = 0;
  85329. public function __construct(\PHPUnit\TextUI\Configuration\TestFileCollection $files)
  85330. {
  85331. $this->files = $files->asArray();
  85332. }
  85333. public function count(): int
  85334. {
  85335. return iterator_count($this);
  85336. }
  85337. public function rewind(): void
  85338. {
  85339. $this->position = 0;
  85340. }
  85341. public function valid(): bool
  85342. {
  85343. return $this->position < count($this->files);
  85344. }
  85345. public function key(): int
  85346. {
  85347. return $this->position;
  85348. }
  85349. public function current(): \PHPUnit\TextUI\Configuration\TestFile
  85350. {
  85351. return $this->files[$this->position];
  85352. }
  85353. public function next(): void
  85354. {
  85355. $this->position++;
  85356. }
  85357. }
  85358. <?php
  85359. declare (strict_types=1);
  85360. /*
  85361. * This file is part of PHPUnit.
  85362. *
  85363. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85364. *
  85365. * For the full copyright and license information, please view the LICENSE
  85366. * file that was distributed with this source code.
  85367. */
  85368. namespace PHPUnit\TextUI\Configuration;
  85369. /**
  85370. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85371. *
  85372. * @psalm-immutable
  85373. */
  85374. final class TestSuite
  85375. {
  85376. /**
  85377. * @psalm-var non-empty-string
  85378. */
  85379. private readonly string $name;
  85380. private readonly \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories;
  85381. private readonly \PHPUnit\TextUI\Configuration\TestFileCollection $files;
  85382. private readonly \PHPUnit\TextUI\Configuration\FileCollection $exclude;
  85383. /**
  85384. * @psalm-param non-empty-string $name
  85385. */
  85386. public function __construct(string $name, \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories, \PHPUnit\TextUI\Configuration\TestFileCollection $files, \PHPUnit\TextUI\Configuration\FileCollection $exclude)
  85387. {
  85388. $this->name = $name;
  85389. $this->directories = $directories;
  85390. $this->files = $files;
  85391. $this->exclude = $exclude;
  85392. }
  85393. /**
  85394. * @psalm-return non-empty-string
  85395. */
  85396. public function name(): string
  85397. {
  85398. return $this->name;
  85399. }
  85400. public function directories(): \PHPUnit\TextUI\Configuration\TestDirectoryCollection
  85401. {
  85402. return $this->directories;
  85403. }
  85404. public function files(): \PHPUnit\TextUI\Configuration\TestFileCollection
  85405. {
  85406. return $this->files;
  85407. }
  85408. public function exclude(): \PHPUnit\TextUI\Configuration\FileCollection
  85409. {
  85410. return $this->exclude;
  85411. }
  85412. }
  85413. <?php
  85414. declare (strict_types=1);
  85415. /*
  85416. * This file is part of PHPUnit.
  85417. *
  85418. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85419. *
  85420. * For the full copyright and license information, please view the LICENSE
  85421. * file that was distributed with this source code.
  85422. */
  85423. namespace PHPUnit\TextUI\Configuration;
  85424. use function count;
  85425. use Countable;
  85426. use IteratorAggregate;
  85427. /**
  85428. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85429. *
  85430. * @psalm-immutable
  85431. *
  85432. * @template-implements IteratorAggregate<int, TestSuite>
  85433. */
  85434. final class TestSuiteCollection implements Countable, IteratorAggregate
  85435. {
  85436. /**
  85437. * @psalm-var list<TestSuite>
  85438. */
  85439. private readonly array $testSuites;
  85440. /**
  85441. * @psalm-param list<TestSuite> $testSuites
  85442. */
  85443. public static function fromArray(array $testSuites): self
  85444. {
  85445. return new self(...$testSuites);
  85446. }
  85447. private function __construct(\PHPUnit\TextUI\Configuration\TestSuite ...$testSuites)
  85448. {
  85449. $this->testSuites = $testSuites;
  85450. }
  85451. /**
  85452. * @psalm-return list<TestSuite>
  85453. */
  85454. public function asArray(): array
  85455. {
  85456. return $this->testSuites;
  85457. }
  85458. public function count(): int
  85459. {
  85460. return count($this->testSuites);
  85461. }
  85462. public function getIterator(): \PHPUnit\TextUI\Configuration\TestSuiteCollectionIterator
  85463. {
  85464. return new \PHPUnit\TextUI\Configuration\TestSuiteCollectionIterator($this);
  85465. }
  85466. public function isEmpty(): bool
  85467. {
  85468. return $this->count() === 0;
  85469. }
  85470. }
  85471. <?php
  85472. declare (strict_types=1);
  85473. /*
  85474. * This file is part of PHPUnit.
  85475. *
  85476. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85477. *
  85478. * For the full copyright and license information, please view the LICENSE
  85479. * file that was distributed with this source code.
  85480. */
  85481. namespace PHPUnit\TextUI\Configuration;
  85482. use function count;
  85483. use function iterator_count;
  85484. use Countable;
  85485. use Iterator;
  85486. /**
  85487. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85488. *
  85489. * @template-implements Iterator<int, TestSuite>
  85490. */
  85491. final class TestSuiteCollectionIterator implements Countable, Iterator
  85492. {
  85493. /**
  85494. * @psalm-var list<TestSuite>
  85495. */
  85496. private readonly array $testSuites;
  85497. private int $position = 0;
  85498. public function __construct(\PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuites)
  85499. {
  85500. $this->testSuites = $testSuites->asArray();
  85501. }
  85502. public function count(): int
  85503. {
  85504. return iterator_count($this);
  85505. }
  85506. public function rewind(): void
  85507. {
  85508. $this->position = 0;
  85509. }
  85510. public function valid(): bool
  85511. {
  85512. return $this->position < count($this->testSuites);
  85513. }
  85514. public function key(): int
  85515. {
  85516. return $this->position;
  85517. }
  85518. public function current(): \PHPUnit\TextUI\Configuration\TestSuite
  85519. {
  85520. return $this->testSuites[$this->position];
  85521. }
  85522. public function next(): void
  85523. {
  85524. $this->position++;
  85525. }
  85526. }
  85527. <?php
  85528. declare (strict_types=1);
  85529. /*
  85530. * This file is part of PHPUnit.
  85531. *
  85532. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85533. *
  85534. * For the full copyright and license information, please view the LICENSE
  85535. * file that was distributed with this source code.
  85536. */
  85537. namespace PHPUnit\TextUI\Configuration;
  85538. /**
  85539. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85540. *
  85541. * @psalm-immutable
  85542. */
  85543. final class Variable
  85544. {
  85545. private readonly string $name;
  85546. private readonly mixed $value;
  85547. private readonly bool $force;
  85548. public function __construct(string $name, mixed $value, bool $force)
  85549. {
  85550. $this->name = $name;
  85551. $this->value = $value;
  85552. $this->force = $force;
  85553. }
  85554. public function name(): string
  85555. {
  85556. return $this->name;
  85557. }
  85558. public function value(): mixed
  85559. {
  85560. return $this->value;
  85561. }
  85562. public function force(): bool
  85563. {
  85564. return $this->force;
  85565. }
  85566. }
  85567. <?php
  85568. declare (strict_types=1);
  85569. /*
  85570. * This file is part of PHPUnit.
  85571. *
  85572. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85573. *
  85574. * For the full copyright and license information, please view the LICENSE
  85575. * file that was distributed with this source code.
  85576. */
  85577. namespace PHPUnit\TextUI\Configuration;
  85578. use function count;
  85579. use Countable;
  85580. use IteratorAggregate;
  85581. /**
  85582. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85583. *
  85584. * @psalm-immutable
  85585. *
  85586. * @template-implements IteratorAggregate<int, Variable>
  85587. */
  85588. final class VariableCollection implements Countable, IteratorAggregate
  85589. {
  85590. /**
  85591. * @psalm-var list<Variable>
  85592. */
  85593. private readonly array $variables;
  85594. /**
  85595. * @psalm-param list<Variable> $variables
  85596. */
  85597. public static function fromArray(array $variables): self
  85598. {
  85599. return new self(...$variables);
  85600. }
  85601. private function __construct(\PHPUnit\TextUI\Configuration\Variable ...$variables)
  85602. {
  85603. $this->variables = $variables;
  85604. }
  85605. /**
  85606. * @psalm-return list<Variable>
  85607. */
  85608. public function asArray(): array
  85609. {
  85610. return $this->variables;
  85611. }
  85612. public function count(): int
  85613. {
  85614. return count($this->variables);
  85615. }
  85616. public function getIterator(): \PHPUnit\TextUI\Configuration\VariableCollectionIterator
  85617. {
  85618. return new \PHPUnit\TextUI\Configuration\VariableCollectionIterator($this);
  85619. }
  85620. }
  85621. <?php
  85622. declare (strict_types=1);
  85623. /*
  85624. * This file is part of PHPUnit.
  85625. *
  85626. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85627. *
  85628. * For the full copyright and license information, please view the LICENSE
  85629. * file that was distributed with this source code.
  85630. */
  85631. namespace PHPUnit\TextUI\Configuration;
  85632. use function count;
  85633. use function iterator_count;
  85634. use Countable;
  85635. use Iterator;
  85636. /**
  85637. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85638. *
  85639. * @template-implements Iterator<int, Variable>
  85640. */
  85641. final class VariableCollectionIterator implements Countable, Iterator
  85642. {
  85643. /**
  85644. * @psalm-var list<Variable>
  85645. */
  85646. private readonly array $variables;
  85647. private int $position = 0;
  85648. public function __construct(\PHPUnit\TextUI\Configuration\VariableCollection $variables)
  85649. {
  85650. $this->variables = $variables->asArray();
  85651. }
  85652. public function count(): int
  85653. {
  85654. return iterator_count($this);
  85655. }
  85656. public function rewind(): void
  85657. {
  85658. $this->position = 0;
  85659. }
  85660. public function valid(): bool
  85661. {
  85662. return $this->position < count($this->variables);
  85663. }
  85664. public function key(): int
  85665. {
  85666. return $this->position;
  85667. }
  85668. public function current(): \PHPUnit\TextUI\Configuration\Variable
  85669. {
  85670. return $this->variables[$this->position];
  85671. }
  85672. public function next(): void
  85673. {
  85674. $this->position++;
  85675. }
  85676. }
  85677. <?php
  85678. declare (strict_types=1);
  85679. /*
  85680. * This file is part of PHPUnit.
  85681. *
  85682. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85683. *
  85684. * For the full copyright and license information, please view the LICENSE
  85685. * file that was distributed with this source code.
  85686. */
  85687. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage;
  85688. use function count;
  85689. use PHPUnit\TextUI\Configuration\Directory;
  85690. use PHPUnit\TextUI\Configuration\FileCollection;
  85691. use PHPUnit\TextUI\Configuration\FilterDirectoryCollection;
  85692. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover;
  85693. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura;
  85694. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j;
  85695. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html;
  85696. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php;
  85697. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text;
  85698. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml;
  85699. use PHPUnit\TextUI\XmlConfiguration\Exception;
  85700. /**
  85701. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85702. *
  85703. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  85704. *
  85705. * @psalm-immutable
  85706. */
  85707. final class CodeCoverage
  85708. {
  85709. private readonly ?Directory $cacheDirectory;
  85710. private readonly FilterDirectoryCollection $directories;
  85711. private readonly FileCollection $files;
  85712. private readonly FilterDirectoryCollection $excludeDirectories;
  85713. private readonly FileCollection $excludeFiles;
  85714. private readonly bool $pathCoverage;
  85715. private readonly bool $includeUncoveredFiles;
  85716. private readonly bool $ignoreDeprecatedCodeUnits;
  85717. private readonly bool $disableCodeCoverageIgnore;
  85718. private readonly ?Clover $clover;
  85719. private readonly ?Cobertura $cobertura;
  85720. private readonly ?Crap4j $crap4j;
  85721. private readonly ?Html $html;
  85722. private readonly ?Php $php;
  85723. private readonly ?Text $text;
  85724. private readonly ?Xml $xml;
  85725. public function __construct(?Directory $cacheDirectory, FilterDirectoryCollection $directories, FileCollection $files, FilterDirectoryCollection $excludeDirectories, FileCollection $excludeFiles, bool $pathCoverage, bool $includeUncoveredFiles, bool $ignoreDeprecatedCodeUnits, bool $disableCodeCoverageIgnore, ?Clover $clover, ?Cobertura $cobertura, ?Crap4j $crap4j, ?Html $html, ?Php $php, ?Text $text, ?Xml $xml)
  85726. {
  85727. $this->cacheDirectory = $cacheDirectory;
  85728. $this->directories = $directories;
  85729. $this->files = $files;
  85730. $this->excludeDirectories = $excludeDirectories;
  85731. $this->excludeFiles = $excludeFiles;
  85732. $this->pathCoverage = $pathCoverage;
  85733. $this->includeUncoveredFiles = $includeUncoveredFiles;
  85734. $this->ignoreDeprecatedCodeUnits = $ignoreDeprecatedCodeUnits;
  85735. $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
  85736. $this->clover = $clover;
  85737. $this->cobertura = $cobertura;
  85738. $this->crap4j = $crap4j;
  85739. $this->html = $html;
  85740. $this->php = $php;
  85741. $this->text = $text;
  85742. $this->xml = $xml;
  85743. }
  85744. /**
  85745. * @psalm-assert-if-true !null $this->cacheDirectory
  85746. *
  85747. * @deprecated
  85748. */
  85749. public function hasCacheDirectory(): bool
  85750. {
  85751. return $this->cacheDirectory !== null;
  85752. }
  85753. /**
  85754. * @throws Exception
  85755. *
  85756. * @deprecated
  85757. */
  85758. public function cacheDirectory(): Directory
  85759. {
  85760. if (!$this->hasCacheDirectory()) {
  85761. throw new Exception('No cache directory has been configured');
  85762. }
  85763. return $this->cacheDirectory;
  85764. }
  85765. public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool
  85766. {
  85767. return count($this->directories) > 0 || count($this->files) > 0;
  85768. }
  85769. public function directories(): FilterDirectoryCollection
  85770. {
  85771. return $this->directories;
  85772. }
  85773. public function files(): FileCollection
  85774. {
  85775. return $this->files;
  85776. }
  85777. public function excludeDirectories(): FilterDirectoryCollection
  85778. {
  85779. return $this->excludeDirectories;
  85780. }
  85781. public function excludeFiles(): FileCollection
  85782. {
  85783. return $this->excludeFiles;
  85784. }
  85785. public function pathCoverage(): bool
  85786. {
  85787. return $this->pathCoverage;
  85788. }
  85789. public function includeUncoveredFiles(): bool
  85790. {
  85791. return $this->includeUncoveredFiles;
  85792. }
  85793. public function ignoreDeprecatedCodeUnits(): bool
  85794. {
  85795. return $this->ignoreDeprecatedCodeUnits;
  85796. }
  85797. public function disableCodeCoverageIgnore(): bool
  85798. {
  85799. return $this->disableCodeCoverageIgnore;
  85800. }
  85801. /**
  85802. * @psalm-assert-if-true !null $this->clover
  85803. */
  85804. public function hasClover(): bool
  85805. {
  85806. return $this->clover !== null;
  85807. }
  85808. /**
  85809. * @throws Exception
  85810. */
  85811. public function clover(): Clover
  85812. {
  85813. if (!$this->hasClover()) {
  85814. throw new Exception('Code Coverage report "Clover XML" has not been configured');
  85815. }
  85816. return $this->clover;
  85817. }
  85818. /**
  85819. * @psalm-assert-if-true !null $this->cobertura
  85820. */
  85821. public function hasCobertura(): bool
  85822. {
  85823. return $this->cobertura !== null;
  85824. }
  85825. /**
  85826. * @throws Exception
  85827. */
  85828. public function cobertura(): Cobertura
  85829. {
  85830. if (!$this->hasCobertura()) {
  85831. throw new Exception('Code Coverage report "Cobertura XML" has not been configured');
  85832. }
  85833. return $this->cobertura;
  85834. }
  85835. /**
  85836. * @psalm-assert-if-true !null $this->crap4j
  85837. */
  85838. public function hasCrap4j(): bool
  85839. {
  85840. return $this->crap4j !== null;
  85841. }
  85842. /**
  85843. * @throws Exception
  85844. */
  85845. public function crap4j(): Crap4j
  85846. {
  85847. if (!$this->hasCrap4j()) {
  85848. throw new Exception('Code Coverage report "Crap4J" has not been configured');
  85849. }
  85850. return $this->crap4j;
  85851. }
  85852. /**
  85853. * @psalm-assert-if-true !null $this->html
  85854. */
  85855. public function hasHtml(): bool
  85856. {
  85857. return $this->html !== null;
  85858. }
  85859. /**
  85860. * @throws Exception
  85861. */
  85862. public function html(): Html
  85863. {
  85864. if (!$this->hasHtml()) {
  85865. throw new Exception('Code Coverage report "HTML" has not been configured');
  85866. }
  85867. return $this->html;
  85868. }
  85869. /**
  85870. * @psalm-assert-if-true !null $this->php
  85871. */
  85872. public function hasPhp(): bool
  85873. {
  85874. return $this->php !== null;
  85875. }
  85876. /**
  85877. * @throws Exception
  85878. */
  85879. public function php(): Php
  85880. {
  85881. if (!$this->hasPhp()) {
  85882. throw new Exception('Code Coverage report "PHP" has not been configured');
  85883. }
  85884. return $this->php;
  85885. }
  85886. /**
  85887. * @psalm-assert-if-true !null $this->text
  85888. */
  85889. public function hasText(): bool
  85890. {
  85891. return $this->text !== null;
  85892. }
  85893. /**
  85894. * @throws Exception
  85895. */
  85896. public function text(): Text
  85897. {
  85898. if (!$this->hasText()) {
  85899. throw new Exception('Code Coverage report "Text" has not been configured');
  85900. }
  85901. return $this->text;
  85902. }
  85903. /**
  85904. * @psalm-assert-if-true !null $this->xml
  85905. */
  85906. public function hasXml(): bool
  85907. {
  85908. return $this->xml !== null;
  85909. }
  85910. /**
  85911. * @throws Exception
  85912. */
  85913. public function xml(): Xml
  85914. {
  85915. if (!$this->hasXml()) {
  85916. throw new Exception('Code Coverage report "XML" has not been configured');
  85917. }
  85918. return $this->xml;
  85919. }
  85920. }
  85921. <?php
  85922. declare (strict_types=1);
  85923. /*
  85924. * This file is part of PHPUnit.
  85925. *
  85926. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85927. *
  85928. * For the full copyright and license information, please view the LICENSE
  85929. * file that was distributed with this source code.
  85930. */
  85931. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  85932. use PHPUnit\TextUI\Configuration\File;
  85933. /**
  85934. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85935. *
  85936. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  85937. *
  85938. * @psalm-immutable
  85939. */
  85940. final class Clover
  85941. {
  85942. private readonly File $target;
  85943. public function __construct(File $target)
  85944. {
  85945. $this->target = $target;
  85946. }
  85947. public function target(): File
  85948. {
  85949. return $this->target;
  85950. }
  85951. }
  85952. <?php
  85953. declare (strict_types=1);
  85954. /*
  85955. * This file is part of PHPUnit.
  85956. *
  85957. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85958. *
  85959. * For the full copyright and license information, please view the LICENSE
  85960. * file that was distributed with this source code.
  85961. */
  85962. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  85963. use PHPUnit\TextUI\Configuration\File;
  85964. /**
  85965. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85966. *
  85967. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  85968. *
  85969. * @psalm-immutable
  85970. */
  85971. final class Cobertura
  85972. {
  85973. private readonly File $target;
  85974. public function __construct(File $target)
  85975. {
  85976. $this->target = $target;
  85977. }
  85978. public function target(): File
  85979. {
  85980. return $this->target;
  85981. }
  85982. }
  85983. <?php
  85984. declare (strict_types=1);
  85985. /*
  85986. * This file is part of PHPUnit.
  85987. *
  85988. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  85989. *
  85990. * For the full copyright and license information, please view the LICENSE
  85991. * file that was distributed with this source code.
  85992. */
  85993. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  85994. use PHPUnit\TextUI\Configuration\File;
  85995. /**
  85996. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  85997. *
  85998. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  85999. *
  86000. * @psalm-immutable
  86001. */
  86002. final class Crap4j
  86003. {
  86004. private readonly File $target;
  86005. private readonly int $threshold;
  86006. public function __construct(File $target, int $threshold)
  86007. {
  86008. $this->target = $target;
  86009. $this->threshold = $threshold;
  86010. }
  86011. public function target(): File
  86012. {
  86013. return $this->target;
  86014. }
  86015. public function threshold(): int
  86016. {
  86017. return $this->threshold;
  86018. }
  86019. }
  86020. <?php
  86021. declare (strict_types=1);
  86022. /*
  86023. * This file is part of PHPUnit.
  86024. *
  86025. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86026. *
  86027. * For the full copyright and license information, please view the LICENSE
  86028. * file that was distributed with this source code.
  86029. */
  86030. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  86031. use PHPUnit\TextUI\Configuration\Directory;
  86032. use PHPUnit\TextUI\Configuration\NoCustomCssFileException;
  86033. /**
  86034. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86035. *
  86036. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86037. *
  86038. * @psalm-immutable
  86039. */
  86040. final class Html
  86041. {
  86042. private readonly Directory $target;
  86043. private readonly int $lowUpperBound;
  86044. private readonly int $highLowerBound;
  86045. private readonly string $colorSuccessLow;
  86046. private readonly string $colorSuccessMedium;
  86047. private readonly string $colorSuccessHigh;
  86048. private readonly string $colorWarning;
  86049. private readonly string $colorDanger;
  86050. private readonly ?string $customCssFile;
  86051. public function __construct(Directory $target, int $lowUpperBound, int $highLowerBound, string $colorSuccessLow, string $colorSuccessMedium, string $colorSuccessHigh, string $colorWarning, string $colorDanger, ?string $customCssFile)
  86052. {
  86053. $this->target = $target;
  86054. $this->lowUpperBound = $lowUpperBound;
  86055. $this->highLowerBound = $highLowerBound;
  86056. $this->colorSuccessLow = $colorSuccessLow;
  86057. $this->colorSuccessMedium = $colorSuccessMedium;
  86058. $this->colorSuccessHigh = $colorSuccessHigh;
  86059. $this->colorWarning = $colorWarning;
  86060. $this->colorDanger = $colorDanger;
  86061. $this->customCssFile = $customCssFile;
  86062. }
  86063. public function target(): Directory
  86064. {
  86065. return $this->target;
  86066. }
  86067. public function lowUpperBound(): int
  86068. {
  86069. return $this->lowUpperBound;
  86070. }
  86071. public function highLowerBound(): int
  86072. {
  86073. return $this->highLowerBound;
  86074. }
  86075. public function colorSuccessLow(): string
  86076. {
  86077. return $this->colorSuccessLow;
  86078. }
  86079. public function colorSuccessMedium(): string
  86080. {
  86081. return $this->colorSuccessMedium;
  86082. }
  86083. public function colorSuccessHigh(): string
  86084. {
  86085. return $this->colorSuccessHigh;
  86086. }
  86087. public function colorWarning(): string
  86088. {
  86089. return $this->colorWarning;
  86090. }
  86091. public function colorDanger(): string
  86092. {
  86093. return $this->colorDanger;
  86094. }
  86095. /**
  86096. * @psalm-assert-if-true !null $this->customCssFile
  86097. */
  86098. public function hasCustomCssFile(): bool
  86099. {
  86100. return $this->customCssFile !== null;
  86101. }
  86102. /**
  86103. * @throws NoCustomCssFileException
  86104. */
  86105. public function customCssFile(): string
  86106. {
  86107. if (!$this->hasCustomCssFile()) {
  86108. throw new NoCustomCssFileException();
  86109. }
  86110. return $this->customCssFile;
  86111. }
  86112. }
  86113. <?php
  86114. declare (strict_types=1);
  86115. /*
  86116. * This file is part of PHPUnit.
  86117. *
  86118. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86119. *
  86120. * For the full copyright and license information, please view the LICENSE
  86121. * file that was distributed with this source code.
  86122. */
  86123. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  86124. use PHPUnit\TextUI\Configuration\File;
  86125. /**
  86126. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86127. *
  86128. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86129. *
  86130. * @psalm-immutable
  86131. */
  86132. final class Php
  86133. {
  86134. private readonly File $target;
  86135. public function __construct(File $target)
  86136. {
  86137. $this->target = $target;
  86138. }
  86139. public function target(): File
  86140. {
  86141. return $this->target;
  86142. }
  86143. }
  86144. <?php
  86145. declare (strict_types=1);
  86146. /*
  86147. * This file is part of PHPUnit.
  86148. *
  86149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86150. *
  86151. * For the full copyright and license information, please view the LICENSE
  86152. * file that was distributed with this source code.
  86153. */
  86154. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  86155. use PHPUnit\TextUI\Configuration\File;
  86156. /**
  86157. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86158. *
  86159. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86160. *
  86161. * @psalm-immutable
  86162. */
  86163. final class Text
  86164. {
  86165. private readonly File $target;
  86166. private readonly bool $showUncoveredFiles;
  86167. private readonly bool $showOnlySummary;
  86168. public function __construct(File $target, bool $showUncoveredFiles, bool $showOnlySummary)
  86169. {
  86170. $this->target = $target;
  86171. $this->showUncoveredFiles = $showUncoveredFiles;
  86172. $this->showOnlySummary = $showOnlySummary;
  86173. }
  86174. public function target(): File
  86175. {
  86176. return $this->target;
  86177. }
  86178. public function showUncoveredFiles(): bool
  86179. {
  86180. return $this->showUncoveredFiles;
  86181. }
  86182. public function showOnlySummary(): bool
  86183. {
  86184. return $this->showOnlySummary;
  86185. }
  86186. }
  86187. <?php
  86188. declare (strict_types=1);
  86189. /*
  86190. * This file is part of PHPUnit.
  86191. *
  86192. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86193. *
  86194. * For the full copyright and license information, please view the LICENSE
  86195. * file that was distributed with this source code.
  86196. */
  86197. namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
  86198. use PHPUnit\TextUI\Configuration\Directory;
  86199. /**
  86200. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86201. *
  86202. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86203. *
  86204. * @psalm-immutable
  86205. */
  86206. final class Xml
  86207. {
  86208. private readonly Directory $target;
  86209. public function __construct(Directory $target)
  86210. {
  86211. $this->target = $target;
  86212. }
  86213. public function target(): Directory
  86214. {
  86215. return $this->target;
  86216. }
  86217. }
  86218. <?php
  86219. declare (strict_types=1);
  86220. /*
  86221. * This file is part of PHPUnit.
  86222. *
  86223. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86224. *
  86225. * For the full copyright and license information, please view the LICENSE
  86226. * file that was distributed with this source code.
  86227. */
  86228. namespace PHPUnit\TextUI\XmlConfiguration;
  86229. use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
  86230. use PHPUnit\TextUI\Configuration\Php;
  86231. use PHPUnit\TextUI\Configuration\Source;
  86232. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  86233. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
  86234. use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
  86235. /**
  86236. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86237. *
  86238. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86239. *
  86240. * @psalm-immutable
  86241. */
  86242. abstract class Configuration
  86243. {
  86244. private readonly ExtensionBootstrapCollection $extensions;
  86245. private readonly Source $source;
  86246. private readonly CodeCoverage $codeCoverage;
  86247. private readonly \PHPUnit\TextUI\XmlConfiguration\Groups $groups;
  86248. private readonly Logging $logging;
  86249. private readonly Php $php;
  86250. private readonly \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit;
  86251. private readonly TestSuiteCollection $testSuite;
  86252. public function __construct(ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite)
  86253. {
  86254. $this->extensions = $extensions;
  86255. $this->source = $source;
  86256. $this->codeCoverage = $codeCoverage;
  86257. $this->groups = $groups;
  86258. $this->logging = $logging;
  86259. $this->php = $php;
  86260. $this->phpunit = $phpunit;
  86261. $this->testSuite = $testSuite;
  86262. }
  86263. public function extensions(): ExtensionBootstrapCollection
  86264. {
  86265. return $this->extensions;
  86266. }
  86267. public function source(): Source
  86268. {
  86269. return $this->source;
  86270. }
  86271. public function codeCoverage(): CodeCoverage
  86272. {
  86273. return $this->codeCoverage;
  86274. }
  86275. public function groups(): \PHPUnit\TextUI\XmlConfiguration\Groups
  86276. {
  86277. return $this->groups;
  86278. }
  86279. public function logging(): Logging
  86280. {
  86281. return $this->logging;
  86282. }
  86283. public function php(): Php
  86284. {
  86285. return $this->php;
  86286. }
  86287. public function phpunit(): \PHPUnit\TextUI\XmlConfiguration\PHPUnit
  86288. {
  86289. return $this->phpunit;
  86290. }
  86291. public function testSuite(): TestSuiteCollection
  86292. {
  86293. return $this->testSuite;
  86294. }
  86295. /**
  86296. * @psalm-assert-if-true DefaultConfiguration $this
  86297. */
  86298. public function isDefault(): bool
  86299. {
  86300. return \false;
  86301. }
  86302. /**
  86303. * @psalm-assert-if-true LoadedFromFileConfiguration $this
  86304. */
  86305. public function wasLoadedFromFile(): bool
  86306. {
  86307. return \false;
  86308. }
  86309. }
  86310. <?php
  86311. declare (strict_types=1);
  86312. /*
  86313. * This file is part of PHPUnit.
  86314. *
  86315. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86316. *
  86317. * For the full copyright and license information, please view the LICENSE
  86318. * file that was distributed with this source code.
  86319. */
  86320. namespace PHPUnit\TextUI\XmlConfiguration;
  86321. use PHPUnit\Runner\TestSuiteSorter;
  86322. use PHPUnit\TextUI\Configuration\ConstantCollection;
  86323. use PHPUnit\TextUI\Configuration\DirectoryCollection;
  86324. use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
  86325. use PHPUnit\TextUI\Configuration\FileCollection;
  86326. use PHPUnit\TextUI\Configuration\FilterDirectoryCollection as CodeCoverageFilterDirectoryCollection;
  86327. use PHPUnit\TextUI\Configuration\GroupCollection;
  86328. use PHPUnit\TextUI\Configuration\IniSettingCollection;
  86329. use PHPUnit\TextUI\Configuration\Php;
  86330. use PHPUnit\TextUI\Configuration\Source;
  86331. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  86332. use PHPUnit\TextUI\Configuration\VariableCollection;
  86333. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
  86334. use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
  86335. /**
  86336. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86337. *
  86338. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86339. *
  86340. * @psalm-immutable
  86341. */
  86342. final class DefaultConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Configuration
  86343. {
  86344. public static function create(): self
  86345. {
  86346. return new self(ExtensionBootstrapCollection::fromArray([]), new Source(null, \false, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), \false, \false, \false, \false, \false, \false, \false, \false, \false, \false), new CodeCoverage(null, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), \false, \true, \false, \false, null, null, null, null, null, null, null), new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray([]), GroupCollection::fromArray([])), new Logging(null, null, null, null), new Php(DirectoryCollection::fromArray([]), IniSettingCollection::fromArray([]), ConstantCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([])), new \PHPUnit\TextUI\XmlConfiguration\PHPUnit(null, \true, null, 80, \PHPUnit\TextUI\Configuration\Configuration::COLOR_DEFAULT, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \true, \false, \false, 1, 1, 10, 60, null, TestSuiteSorter::ORDER_DEFAULT, \true, \false, \false, \false, \false, \false, \false, 100), TestSuiteCollection::fromArray([]));
  86347. }
  86348. public function isDefault(): bool
  86349. {
  86350. return \true;
  86351. }
  86352. }
  86353. <?php
  86354. declare (strict_types=1);
  86355. /*
  86356. * This file is part of PHPUnit.
  86357. *
  86358. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86359. *
  86360. * For the full copyright and license information, please view the LICENSE
  86361. * file that was distributed with this source code.
  86362. */
  86363. namespace PHPUnit\TextUI\XmlConfiguration;
  86364. use RuntimeException;
  86365. /**
  86366. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86367. *
  86368. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86369. */
  86370. final class Exception extends RuntimeException implements \PHPUnit\Exception
  86371. {
  86372. }
  86373. <?php
  86374. declare (strict_types=1);
  86375. /*
  86376. * This file is part of PHPUnit.
  86377. *
  86378. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86379. *
  86380. * For the full copyright and license information, please view the LICENSE
  86381. * file that was distributed with this source code.
  86382. */
  86383. namespace PHPUnit\TextUI\XmlConfiguration;
  86384. use function str_replace;
  86385. /**
  86386. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86387. *
  86388. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86389. */
  86390. final class Generator
  86391. {
  86392. /**
  86393. * @var string
  86394. */
  86395. private const TEMPLATE = <<<'EOT'
  86396. <?xml version="1.0" encoding="UTF-8"?>
  86397. <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  86398. xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/{phpunit_version}/phpunit.xsd"
  86399. bootstrap="{bootstrap_script}"
  86400. cacheDirectory="{cache_directory}"
  86401. executionOrder="depends,defects"
  86402. requireCoverageMetadata="true"
  86403. beStrictAboutCoverageMetadata="true"
  86404. beStrictAboutOutputDuringTests="true"
  86405. displayDetailsOnPhpunitDeprecations="true"
  86406. failOnPhpunitDeprecation="true"
  86407. failOnRisky="true"
  86408. failOnWarning="true">
  86409. <testsuites>
  86410. <testsuite name="default">
  86411. <directory>{tests_directory}</directory>
  86412. </testsuite>
  86413. </testsuites>
  86414. <source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
  86415. <include>
  86416. <directory>{src_directory}</directory>
  86417. </include>
  86418. </source>
  86419. </phpunit>
  86420. EOT;
  86421. public function generateDefaultConfiguration(string $phpunitVersion, string $bootstrapScript, string $testsDirectory, string $srcDirectory, string $cacheDirectory): string
  86422. {
  86423. return str_replace(['{phpunit_version}', '{bootstrap_script}', '{tests_directory}', '{src_directory}', '{cache_directory}'], [$phpunitVersion, $bootstrapScript, $testsDirectory, $srcDirectory, $cacheDirectory], self::TEMPLATE);
  86424. }
  86425. }
  86426. <?php
  86427. declare (strict_types=1);
  86428. /*
  86429. * This file is part of PHPUnit.
  86430. *
  86431. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86432. *
  86433. * For the full copyright and license information, please view the LICENSE
  86434. * file that was distributed with this source code.
  86435. */
  86436. namespace PHPUnit\TextUI\XmlConfiguration;
  86437. use PHPUnit\TextUI\Configuration\GroupCollection;
  86438. /**
  86439. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86440. *
  86441. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86442. *
  86443. * @psalm-immutable
  86444. */
  86445. final class Groups
  86446. {
  86447. private readonly GroupCollection $include;
  86448. private readonly GroupCollection $exclude;
  86449. public function __construct(GroupCollection $include, GroupCollection $exclude)
  86450. {
  86451. $this->include = $include;
  86452. $this->exclude = $exclude;
  86453. }
  86454. public function hasInclude(): bool
  86455. {
  86456. return !$this->include->isEmpty();
  86457. }
  86458. public function include(): GroupCollection
  86459. {
  86460. return $this->include;
  86461. }
  86462. public function hasExclude(): bool
  86463. {
  86464. return !$this->exclude->isEmpty();
  86465. }
  86466. public function exclude(): GroupCollection
  86467. {
  86468. return $this->exclude;
  86469. }
  86470. }
  86471. <?php
  86472. declare (strict_types=1);
  86473. /*
  86474. * This file is part of PHPUnit.
  86475. *
  86476. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86477. *
  86478. * For the full copyright and license information, please view the LICENSE
  86479. * file that was distributed with this source code.
  86480. */
  86481. namespace PHPUnit\TextUI\XmlConfiguration;
  86482. use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
  86483. use PHPUnit\TextUI\Configuration\Php;
  86484. use PHPUnit\TextUI\Configuration\Source;
  86485. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  86486. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
  86487. use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
  86488. /**
  86489. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86490. *
  86491. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86492. *
  86493. * @psalm-immutable
  86494. */
  86495. final class LoadedFromFileConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Configuration
  86496. {
  86497. private readonly string $filename;
  86498. private readonly \PHPUnit\TextUI\XmlConfiguration\ValidationResult $validationResult;
  86499. public function __construct(string $filename, \PHPUnit\TextUI\XmlConfiguration\ValidationResult $validationResult, ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite)
  86500. {
  86501. $this->filename = $filename;
  86502. $this->validationResult = $validationResult;
  86503. parent::__construct($extensions, $source, $codeCoverage, $groups, $logging, $php, $phpunit, $testSuite);
  86504. }
  86505. public function filename(): string
  86506. {
  86507. return $this->filename;
  86508. }
  86509. public function hasValidationErrors(): bool
  86510. {
  86511. return $this->validationResult->hasValidationErrors();
  86512. }
  86513. public function validationErrors(): string
  86514. {
  86515. return $this->validationResult->asString();
  86516. }
  86517. public function wasLoadedFromFile(): bool
  86518. {
  86519. return \true;
  86520. }
  86521. }
  86522. <?php
  86523. declare (strict_types=1);
  86524. /*
  86525. * This file is part of PHPUnit.
  86526. *
  86527. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  86528. *
  86529. * For the full copyright and license information, please view the LICENSE
  86530. * file that was distributed with this source code.
  86531. */
  86532. namespace PHPUnit\TextUI\XmlConfiguration;
  86533. use const DIRECTORY_SEPARATOR;
  86534. use const PHP_VERSION;
  86535. use function assert;
  86536. use function defined;
  86537. use function dirname;
  86538. use function explode;
  86539. use function is_numeric;
  86540. use function preg_match;
  86541. use function realpath;
  86542. use function str_contains;
  86543. use function str_starts_with;
  86544. use function strlen;
  86545. use function strtolower;
  86546. use function substr;
  86547. use function trim;
  86548. use DOMDocument;
  86549. use DOMElement;
  86550. use DOMNode;
  86551. use DOMXPath;
  86552. use PHPUnit\Runner\TestSuiteSorter;
  86553. use PHPUnit\Runner\Version;
  86554. use PHPUnit\TextUI\Configuration\Configuration;
  86555. use PHPUnit\TextUI\Configuration\Constant;
  86556. use PHPUnit\TextUI\Configuration\ConstantCollection;
  86557. use PHPUnit\TextUI\Configuration\Directory;
  86558. use PHPUnit\TextUI\Configuration\DirectoryCollection;
  86559. use PHPUnit\TextUI\Configuration\ExtensionBootstrap;
  86560. use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
  86561. use PHPUnit\TextUI\Configuration\File;
  86562. use PHPUnit\TextUI\Configuration\FileCollection;
  86563. use PHPUnit\TextUI\Configuration\FilterDirectory;
  86564. use PHPUnit\TextUI\Configuration\FilterDirectoryCollection;
  86565. use PHPUnit\TextUI\Configuration\Group;
  86566. use PHPUnit\TextUI\Configuration\GroupCollection;
  86567. use PHPUnit\TextUI\Configuration\IniSetting;
  86568. use PHPUnit\TextUI\Configuration\IniSettingCollection;
  86569. use PHPUnit\TextUI\Configuration\Php;
  86570. use PHPUnit\TextUI\Configuration\Source;
  86571. use PHPUnit\TextUI\Configuration\TestDirectory;
  86572. use PHPUnit\TextUI\Configuration\TestDirectoryCollection;
  86573. use PHPUnit\TextUI\Configuration\TestFile;
  86574. use PHPUnit\TextUI\Configuration\TestFileCollection;
  86575. use PHPUnit\TextUI\Configuration\TestSuite as TestSuiteConfiguration;
  86576. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  86577. use PHPUnit\TextUI\Configuration\Variable;
  86578. use PHPUnit\TextUI\Configuration\VariableCollection;
  86579. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
  86580. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover;
  86581. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura;
  86582. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j;
  86583. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html as CodeCoverageHtml;
  86584. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php as CodeCoveragePhp;
  86585. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text as CodeCoverageText;
  86586. use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml as CodeCoverageXml;
  86587. use PHPUnit\TextUI\XmlConfiguration\Logging\Junit;
  86588. use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
  86589. use PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity;
  86590. use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml;
  86591. use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText;
  86592. use PHPUnit\Util\VersionComparisonOperator;
  86593. use PHPUnit\Util\Xml\Loader as XmlLoader;
  86594. use PHPUnit\Util\Xml\XmlException;
  86595. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
  86596. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
  86597. /**
  86598. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  86599. *
  86600. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  86601. */
  86602. final class Loader
  86603. {
  86604. /**
  86605. * @throws Exception
  86606. */
  86607. public function load(string $filename): \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration
  86608. {
  86609. try {
  86610. $document = (new XmlLoader())->loadFile($filename);
  86611. } catch (XmlException $e) {
  86612. throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e);
  86613. }
  86614. $xpath = new DOMXPath($document);
  86615. try {
  86616. $xsdFilename = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find(Version::series());
  86617. } catch (\PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException $e) {
  86618. throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e);
  86619. }
  86620. $configurationFileRealpath = realpath($filename);
  86621. return new \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration($configurationFileRealpath, (new \PHPUnit\TextUI\XmlConfiguration\Validator())->validate($document, $xsdFilename), $this->extensions($xpath), $this->source($configurationFileRealpath, $xpath), $this->codeCoverage($configurationFileRealpath, $xpath), $this->groups($xpath), $this->logging($configurationFileRealpath, $xpath), $this->php($configurationFileRealpath, $xpath), $this->phpunit($configurationFileRealpath, $document), $this->testSuite($configurationFileRealpath, $xpath));
  86622. }
  86623. private function logging(string $filename, DOMXPath $xpath): Logging
  86624. {
  86625. $junit = null;
  86626. $element = $this->element($xpath, 'logging/junit');
  86627. if ($element) {
  86628. $junit = new Junit(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86629. }
  86630. $teamCity = null;
  86631. $element = $this->element($xpath, 'logging/teamcity');
  86632. if ($element) {
  86633. $teamCity = new TeamCity(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86634. }
  86635. $testDoxHtml = null;
  86636. $element = $this->element($xpath, 'logging/testdoxHtml');
  86637. if ($element) {
  86638. $testDoxHtml = new TestDoxHtml(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86639. }
  86640. $testDoxText = null;
  86641. $element = $this->element($xpath, 'logging/testdoxText');
  86642. if ($element) {
  86643. $testDoxText = new TestDoxText(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86644. }
  86645. return new Logging($junit, $teamCity, $testDoxHtml, $testDoxText);
  86646. }
  86647. private function extensions(DOMXPath $xpath): ExtensionBootstrapCollection
  86648. {
  86649. $extensionBootstrappers = [];
  86650. foreach ($xpath->query('extensions/bootstrap') as $bootstrap) {
  86651. assert($bootstrap instanceof DOMElement);
  86652. $parameters = [];
  86653. foreach ($xpath->query('parameter', $bootstrap) as $parameter) {
  86654. assert($parameter instanceof DOMElement);
  86655. $parameters[$parameter->getAttribute('name')] = $parameter->getAttribute('value');
  86656. }
  86657. $extensionBootstrappers[] = new ExtensionBootstrap($bootstrap->getAttribute('class'), $parameters);
  86658. }
  86659. return ExtensionBootstrapCollection::fromArray($extensionBootstrappers);
  86660. }
  86661. /**
  86662. * @psalm-return non-empty-string
  86663. */
  86664. private function toAbsolutePath(string $filename, string $path): string
  86665. {
  86666. $path = trim($path);
  86667. if (str_starts_with($path, '/')) {
  86668. return $path;
  86669. }
  86670. // Matches the following on Windows:
  86671. // - \\NetworkComputer\Path
  86672. // - \\.\D:
  86673. // - \\.\c:
  86674. // - C:\Windows
  86675. // - C:\windows
  86676. // - C:/windows
  86677. // - c:/windows
  86678. if (defined('PHP_WINDOWS_VERSION_BUILD') && !empty($path) && ($path[0] === '\\' || strlen($path) >= 3 && preg_match('#^[A-Z]:[/\\\\]#i', substr($path, 0, 3)))) {
  86679. return $path;
  86680. }
  86681. if (str_contains($path, '://')) {
  86682. return $path;
  86683. }
  86684. return dirname($filename) . DIRECTORY_SEPARATOR . $path;
  86685. }
  86686. private function source(string $filename, DOMXPath $xpath): Source
  86687. {
  86688. $baseline = null;
  86689. $restrictDeprecations = \false;
  86690. $restrictNotices = \false;
  86691. $restrictWarnings = \false;
  86692. $ignoreSuppressionOfDeprecations = \false;
  86693. $ignoreSuppressionOfPhpDeprecations = \false;
  86694. $ignoreSuppressionOfErrors = \false;
  86695. $ignoreSuppressionOfNotices = \false;
  86696. $ignoreSuppressionOfPhpNotices = \false;
  86697. $ignoreSuppressionOfWarnings = \false;
  86698. $ignoreSuppressionOfPhpWarnings = \false;
  86699. $element = $this->element($xpath, 'source');
  86700. if ($element) {
  86701. $baseline = $this->getStringAttribute($element, 'baseline');
  86702. if ($baseline !== null) {
  86703. $baseline = $this->toAbsolutePath($filename, $baseline);
  86704. }
  86705. $restrictDeprecations = $this->getBooleanAttribute($element, 'restrictDeprecations', \false);
  86706. $restrictNotices = $this->getBooleanAttribute($element, 'restrictNotices', \false);
  86707. $restrictWarnings = $this->getBooleanAttribute($element, 'restrictWarnings', \false);
  86708. $ignoreSuppressionOfDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfDeprecations', \false);
  86709. $ignoreSuppressionOfPhpDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpDeprecations', \false);
  86710. $ignoreSuppressionOfErrors = $this->getBooleanAttribute($element, 'ignoreSuppressionOfErrors', \false);
  86711. $ignoreSuppressionOfNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfNotices', \false);
  86712. $ignoreSuppressionOfPhpNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpNotices', \false);
  86713. $ignoreSuppressionOfWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfWarnings', \false);
  86714. $ignoreSuppressionOfPhpWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpWarnings', \false);
  86715. }
  86716. return new Source($baseline, \false, $this->readFilterDirectories($filename, $xpath, 'source/include/directory'), $this->readFilterFiles($filename, $xpath, 'source/include/file'), $this->readFilterDirectories($filename, $xpath, 'source/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'source/exclude/file'), $restrictDeprecations, $restrictNotices, $restrictWarnings, $ignoreSuppressionOfDeprecations, $ignoreSuppressionOfPhpDeprecations, $ignoreSuppressionOfErrors, $ignoreSuppressionOfNotices, $ignoreSuppressionOfPhpNotices, $ignoreSuppressionOfWarnings, $ignoreSuppressionOfPhpWarnings);
  86717. }
  86718. private function codeCoverage(string $filename, DOMXPath $xpath): CodeCoverage
  86719. {
  86720. $cacheDirectory = null;
  86721. $pathCoverage = \false;
  86722. $includeUncoveredFiles = \true;
  86723. $ignoreDeprecatedCodeUnits = \false;
  86724. $disableCodeCoverageIgnore = \false;
  86725. $element = $this->element($xpath, 'coverage');
  86726. if ($element) {
  86727. $cacheDirectory = $this->getStringAttribute($element, 'cacheDirectory');
  86728. if ($cacheDirectory !== null) {
  86729. $cacheDirectory = new Directory($this->toAbsolutePath($filename, $cacheDirectory));
  86730. }
  86731. $pathCoverage = $this->getBooleanAttribute($element, 'pathCoverage', \false);
  86732. $includeUncoveredFiles = $this->getBooleanAttribute($element, 'includeUncoveredFiles', \true);
  86733. $ignoreDeprecatedCodeUnits = $this->getBooleanAttribute($element, 'ignoreDeprecatedCodeUnits', \false);
  86734. $disableCodeCoverageIgnore = $this->getBooleanAttribute($element, 'disableCodeCoverageIgnore', \false);
  86735. }
  86736. $clover = null;
  86737. $element = $this->element($xpath, 'coverage/report/clover');
  86738. if ($element) {
  86739. $clover = new Clover(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86740. }
  86741. $cobertura = null;
  86742. $element = $this->element($xpath, 'coverage/report/cobertura');
  86743. if ($element) {
  86744. $cobertura = new Cobertura(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86745. }
  86746. $crap4j = null;
  86747. $element = $this->element($xpath, 'coverage/report/crap4j');
  86748. if ($element) {
  86749. $crap4j = new Crap4j(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))), $this->getIntegerAttribute($element, 'threshold', 30));
  86750. }
  86751. $html = null;
  86752. $element = $this->element($xpath, 'coverage/report/html');
  86753. if ($element) {
  86754. $defaultColors = Colors::default();
  86755. $defaultThresholds = Thresholds::default();
  86756. $html = new CodeCoverageHtml(new Directory($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputDirectory'))), $this->getIntegerAttribute($element, 'lowUpperBound', $defaultThresholds->lowUpperBound()), $this->getIntegerAttribute($element, 'highLowerBound', $defaultThresholds->highLowerBound()), $this->getStringAttributeWithDefault($element, 'colorSuccessLow', $defaultColors->successLow()), $this->getStringAttributeWithDefault($element, 'colorSuccessMedium', $defaultColors->successMedium()), $this->getStringAttributeWithDefault($element, 'colorSuccessHigh', $defaultColors->successHigh()), $this->getStringAttributeWithDefault($element, 'colorWarning', $defaultColors->warning()), $this->getStringAttributeWithDefault($element, 'colorDanger', $defaultColors->danger()), $this->getStringAttribute($element, 'customCssFile'));
  86757. }
  86758. $php = null;
  86759. $element = $this->element($xpath, 'coverage/report/php');
  86760. if ($element) {
  86761. $php = new CodeCoveragePhp(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
  86762. }
  86763. $text = null;
  86764. $element = $this->element($xpath, 'coverage/report/text');
  86765. if ($element) {
  86766. $text = new CodeCoverageText(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))), $this->getBooleanAttribute($element, 'showUncoveredFiles', \false), $this->getBooleanAttribute($element, 'showOnlySummary', \false));
  86767. }
  86768. $xml = null;
  86769. $element = $this->element($xpath, 'coverage/report/xml');
  86770. if ($element) {
  86771. $xml = new CodeCoverageXml(new Directory($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputDirectory'))));
  86772. }
  86773. return new CodeCoverage($cacheDirectory, $this->readFilterDirectories($filename, $xpath, 'coverage/include/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/include/file'), $this->readFilterDirectories($filename, $xpath, 'coverage/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/exclude/file'), $pathCoverage, $includeUncoveredFiles, $ignoreDeprecatedCodeUnits, $disableCodeCoverageIgnore, $clover, $cobertura, $crap4j, $html, $php, $text, $xml);
  86774. }
  86775. private function getBoolean(string $value, bool $default): bool
  86776. {
  86777. if (strtolower($value) === 'false') {
  86778. return \false;
  86779. }
  86780. if (strtolower($value) === 'true') {
  86781. return \true;
  86782. }
  86783. return $default;
  86784. }
  86785. private function getValue(string $value): bool|string
  86786. {
  86787. if (strtolower($value) === 'false') {
  86788. return \false;
  86789. }
  86790. if (strtolower($value) === 'true') {
  86791. return \true;
  86792. }
  86793. return $value;
  86794. }
  86795. private function readFilterDirectories(string $filename, DOMXPath $xpath, string $query): FilterDirectoryCollection
  86796. {
  86797. $directories = [];
  86798. foreach ($xpath->query($query) as $directoryNode) {
  86799. assert($directoryNode instanceof DOMElement);
  86800. $directoryPath = $directoryNode->textContent;
  86801. if (!$directoryPath) {
  86802. continue;
  86803. }
  86804. $directories[] = new FilterDirectory($this->toAbsolutePath($filename, $directoryPath), $directoryNode->hasAttribute('prefix') ? $directoryNode->getAttribute('prefix') : '', $directoryNode->hasAttribute('suffix') ? $directoryNode->getAttribute('suffix') : '.php');
  86805. }
  86806. return FilterDirectoryCollection::fromArray($directories);
  86807. }
  86808. private function readFilterFiles(string $filename, DOMXPath $xpath, string $query): FileCollection
  86809. {
  86810. $files = [];
  86811. foreach ($xpath->query($query) as $file) {
  86812. assert($file instanceof DOMNode);
  86813. $filePath = $file->textContent;
  86814. if ($filePath) {
  86815. $files[] = new File($this->toAbsolutePath($filename, $filePath));
  86816. }
  86817. }
  86818. return FileCollection::fromArray($files);
  86819. }
  86820. private function groups(DOMXPath $xpath): \PHPUnit\TextUI\XmlConfiguration\Groups
  86821. {
  86822. $include = [];
  86823. $exclude = [];
  86824. foreach ($xpath->query('groups/include/group') as $group) {
  86825. assert($group instanceof DOMNode);
  86826. $include[] = new Group($group->textContent);
  86827. }
  86828. foreach ($xpath->query('groups/exclude/group') as $group) {
  86829. assert($group instanceof DOMNode);
  86830. $exclude[] = new Group($group->textContent);
  86831. }
  86832. return new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray($include), GroupCollection::fromArray($exclude));
  86833. }
  86834. private function getBooleanAttribute(DOMElement $element, string $attribute, bool $default): bool
  86835. {
  86836. if (!$element->hasAttribute($attribute)) {
  86837. return $default;
  86838. }
  86839. return $this->getBoolean($element->getAttribute($attribute), \false);
  86840. }
  86841. private function getIntegerAttribute(DOMElement $element, string $attribute, int $default): int
  86842. {
  86843. if (!$element->hasAttribute($attribute)) {
  86844. return $default;
  86845. }
  86846. return $this->getInteger($element->getAttribute($attribute), $default);
  86847. }
  86848. private function getStringAttribute(DOMElement $element, string $attribute): ?string
  86849. {
  86850. if (!$element->hasAttribute($attribute)) {
  86851. return null;
  86852. }
  86853. return $element->getAttribute($attribute);
  86854. }
  86855. private function getStringAttributeWithDefault(DOMElement $element, string $attribute, string $default): string
  86856. {
  86857. if (!$element->hasAttribute($attribute)) {
  86858. return $default;
  86859. }
  86860. return $element->getAttribute($attribute);
  86861. }
  86862. private function getInteger(string $value, int $default): int
  86863. {
  86864. if (is_numeric($value)) {
  86865. return (int) $value;
  86866. }
  86867. return $default;
  86868. }
  86869. private function php(string $filename, DOMXPath $xpath): Php
  86870. {
  86871. $includePaths = [];
  86872. foreach ($xpath->query('php/includePath') as $includePath) {
  86873. assert($includePath instanceof DOMNode);
  86874. $path = $includePath->textContent;
  86875. if ($path) {
  86876. $includePaths[] = new Directory($this->toAbsolutePath($filename, $path));
  86877. }
  86878. }
  86879. $iniSettings = [];
  86880. foreach ($xpath->query('php/ini') as $ini) {
  86881. assert($ini instanceof DOMElement);
  86882. $iniSettings[] = new IniSetting($ini->getAttribute('name'), $ini->getAttribute('value'));
  86883. }
  86884. $constants = [];
  86885. foreach ($xpath->query('php/const') as $const) {
  86886. assert($const instanceof DOMElement);
  86887. $value = $const->getAttribute('value');
  86888. $constants[] = new Constant($const->getAttribute('name'), $this->getValue($value));
  86889. }
  86890. $variables = ['var' => [], 'env' => [], 'post' => [], 'get' => [], 'cookie' => [], 'server' => [], 'files' => [], 'request' => []];
  86891. foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) {
  86892. foreach ($xpath->query('php/' . $array) as $var) {
  86893. assert($var instanceof DOMElement);
  86894. $name = $var->getAttribute('name');
  86895. $value = $var->getAttribute('value');
  86896. $force = \false;
  86897. $verbatim = \false;
  86898. if ($var->hasAttribute('force')) {
  86899. $force = $this->getBoolean($var->getAttribute('force'), \false);
  86900. }
  86901. if ($var->hasAttribute('verbatim')) {
  86902. $verbatim = $this->getBoolean($var->getAttribute('verbatim'), \false);
  86903. }
  86904. if (!$verbatim) {
  86905. $value = $this->getValue($value);
  86906. }
  86907. $variables[$array][] = new Variable($name, $value, $force);
  86908. }
  86909. }
  86910. return new Php(DirectoryCollection::fromArray($includePaths), IniSettingCollection::fromArray($iniSettings), ConstantCollection::fromArray($constants), VariableCollection::fromArray($variables['var']), VariableCollection::fromArray($variables['env']), VariableCollection::fromArray($variables['post']), VariableCollection::fromArray($variables['get']), VariableCollection::fromArray($variables['cookie']), VariableCollection::fromArray($variables['server']), VariableCollection::fromArray($variables['files']), VariableCollection::fromArray($variables['request']));
  86911. }
  86912. private function phpunit(string $filename, DOMDocument $document): \PHPUnit\TextUI\XmlConfiguration\PHPUnit
  86913. {
  86914. $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
  86915. $defectsFirst = \false;
  86916. $resolveDependencies = $this->getBooleanAttribute($document->documentElement, 'resolveDependencies', \true);
  86917. if ($document->documentElement->hasAttribute('executionOrder')) {
  86918. foreach (explode(',', $document->documentElement->getAttribute('executionOrder')) as $order) {
  86919. switch ($order) {
  86920. case 'default':
  86921. $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
  86922. $defectsFirst = \false;
  86923. $resolveDependencies = \true;
  86924. break;
  86925. case 'depends':
  86926. $resolveDependencies = \true;
  86927. break;
  86928. case 'no-depends':
  86929. $resolveDependencies = \false;
  86930. break;
  86931. case 'defects':
  86932. $defectsFirst = \true;
  86933. break;
  86934. case 'duration':
  86935. $executionOrder = TestSuiteSorter::ORDER_DURATION;
  86936. break;
  86937. case 'random':
  86938. $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
  86939. break;
  86940. case 'reverse':
  86941. $executionOrder = TestSuiteSorter::ORDER_REVERSED;
  86942. break;
  86943. case 'size':
  86944. $executionOrder = TestSuiteSorter::ORDER_SIZE;
  86945. break;
  86946. }
  86947. }
  86948. }
  86949. $cacheDirectory = $this->getStringAttribute($document->documentElement, 'cacheDirectory');
  86950. if ($cacheDirectory !== null) {
  86951. $cacheDirectory = $this->toAbsolutePath($filename, $cacheDirectory);
  86952. }
  86953. $cacheResultFile = $this->getStringAttribute($document->documentElement, 'cacheResultFile');
  86954. if ($cacheResultFile !== null) {
  86955. $cacheResultFile = $this->toAbsolutePath($filename, $cacheResultFile);
  86956. }
  86957. $bootstrap = $this->getStringAttribute($document->documentElement, 'bootstrap');
  86958. if ($bootstrap !== null) {
  86959. $bootstrap = $this->toAbsolutePath($filename, $bootstrap);
  86960. }
  86961. $extensionsDirectory = $this->getStringAttribute($document->documentElement, 'extensionsDirectory');
  86962. if ($extensionsDirectory !== null) {
  86963. $extensionsDirectory = $this->toAbsolutePath($filename, $extensionsDirectory);
  86964. }
  86965. $backupStaticProperties = \false;
  86966. if ($document->documentElement->hasAttribute('backupStaticProperties')) {
  86967. $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticProperties', \false);
  86968. } elseif ($document->documentElement->hasAttribute('backupStaticAttributes')) {
  86969. $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticAttributes', \false);
  86970. }
  86971. $requireCoverageMetadata = \false;
  86972. if ($document->documentElement->hasAttribute('requireCoverageMetadata')) {
  86973. $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'requireCoverageMetadata', \false);
  86974. } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
  86975. $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'forceCoversAnnotation', \false);
  86976. }
  86977. $beStrictAboutCoverageMetadata = \false;
  86978. if ($document->documentElement->hasAttribute('beStrictAboutCoverageMetadata')) {
  86979. $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoverageMetadata', \false);
  86980. } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
  86981. $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', \false);
  86982. }
  86983. return new \PHPUnit\TextUI\XmlConfiguration\PHPUnit($cacheDirectory, $this->getBooleanAttribute($document->documentElement, 'cacheResult', \true), $cacheResultFile, $this->getColumns($document), $this->getColors($document), $this->getBooleanAttribute($document->documentElement, 'stderr', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnIncompleteTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnSkippedTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerDeprecations', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnPhpunitDeprecations', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerErrors', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerNotices', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerWarnings', \false), $this->getBooleanAttribute($document->documentElement, 'reverseDefectList', \false), $requireCoverageMetadata, $bootstrap, $this->getBooleanAttribute($document->documentElement, 'processIsolation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnPhpunitDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnEmptyTestSuite', \false), $this->getBooleanAttribute($document->documentElement, 'failOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'failOnNotice', \false), $this->getBooleanAttribute($document->documentElement, 'failOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'failOnSkipped', \false), $this->getBooleanAttribute($document->documentElement, 'failOnWarning', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnDefect', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnError', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnFailure', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnNotice', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnSkipped', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnWarning', \false), $extensionsDirectory, $this->getBooleanAttribute($document->documentElement, 'beStrictAboutChangesToGlobalState', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutOutputDuringTests', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutTestsThatDoNotTestAnything', \true), $beStrictAboutCoverageMetadata, $this->getBooleanAttribute($document->documentElement, 'enforceTimeLimit', \false), $this->getIntegerAttribute($document->documentElement, 'defaultTimeLimit', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForSmallTests', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForMediumTests', 10), $this->getIntegerAttribute($document->documentElement, 'timeoutForLargeTests', 60), $this->getStringAttribute($document->documentElement, 'defaultTestSuite'), $executionOrder, $resolveDependencies, $defectsFirst, $this->getBooleanAttribute($document->documentElement, 'backupGlobals', \false), $backupStaticProperties, $this->getBooleanAttribute($document->documentElement, 'registerMockObjectsFromTestArgumentsRecursively', \false), $this->getBooleanAttribute($document->documentElement, 'testdox', \false), $this->getBooleanAttribute($document->documentElement, 'controlGarbageCollector', \false), $this->getIntegerAttribute($document->documentElement, 'numberOfTestsBeforeGarbageCollection', 100));
  86984. }
  86985. private function getColors(DOMDocument $document): string
  86986. {
  86987. $colors = Configuration::COLOR_DEFAULT;
  86988. if ($document->documentElement->hasAttribute('colors')) {
  86989. /* only allow boolean for compatibility with previous versions
  86990. 'always' only allowed from command line */
  86991. if ($this->getBoolean($document->documentElement->getAttribute('colors'), \false)) {
  86992. $colors = Configuration::COLOR_AUTO;
  86993. } else {
  86994. $colors = Configuration::COLOR_NEVER;
  86995. }
  86996. }
  86997. return $colors;
  86998. }
  86999. private function getColumns(DOMDocument $document): int|string
  87000. {
  87001. $columns = 80;
  87002. if ($document->documentElement->hasAttribute('columns')) {
  87003. $columns = $document->documentElement->getAttribute('columns');
  87004. if ($columns !== 'max') {
  87005. $columns = $this->getInteger($columns, 80);
  87006. }
  87007. }
  87008. return $columns;
  87009. }
  87010. private function testSuite(string $filename, DOMXPath $xpath): TestSuiteCollection
  87011. {
  87012. $testSuites = [];
  87013. foreach ($this->getTestSuiteElements($xpath) as $element) {
  87014. $exclude = [];
  87015. foreach ($element->getElementsByTagName('exclude') as $excludeNode) {
  87016. $excludeFile = $excludeNode->textContent;
  87017. if ($excludeFile) {
  87018. $exclude[] = new File($this->toAbsolutePath($filename, $excludeFile));
  87019. }
  87020. }
  87021. $directories = [];
  87022. foreach ($element->getElementsByTagName('directory') as $directoryNode) {
  87023. assert($directoryNode instanceof DOMElement);
  87024. $directory = $directoryNode->textContent;
  87025. if (empty($directory)) {
  87026. continue;
  87027. }
  87028. $prefix = '';
  87029. if ($directoryNode->hasAttribute('prefix')) {
  87030. $prefix = $directoryNode->getAttribute('prefix');
  87031. }
  87032. $suffix = 'Test.php';
  87033. if ($directoryNode->hasAttribute('suffix')) {
  87034. $suffix = $directoryNode->getAttribute('suffix');
  87035. }
  87036. $phpVersion = PHP_VERSION;
  87037. if ($directoryNode->hasAttribute('phpVersion')) {
  87038. $phpVersion = $directoryNode->getAttribute('phpVersion');
  87039. }
  87040. $phpVersionOperator = new VersionComparisonOperator('>=');
  87041. if ($directoryNode->hasAttribute('phpVersionOperator')) {
  87042. $phpVersionOperator = new VersionComparisonOperator($directoryNode->getAttribute('phpVersionOperator'));
  87043. }
  87044. $directories[] = new TestDirectory($this->toAbsolutePath($filename, $directory), $prefix, $suffix, $phpVersion, $phpVersionOperator);
  87045. }
  87046. $files = [];
  87047. foreach ($element->getElementsByTagName('file') as $fileNode) {
  87048. assert($fileNode instanceof DOMElement);
  87049. $file = $fileNode->textContent;
  87050. if (empty($file)) {
  87051. continue;
  87052. }
  87053. $phpVersion = PHP_VERSION;
  87054. if ($fileNode->hasAttribute('phpVersion')) {
  87055. $phpVersion = $fileNode->getAttribute('phpVersion');
  87056. }
  87057. $phpVersionOperator = new VersionComparisonOperator('>=');
  87058. if ($fileNode->hasAttribute('phpVersionOperator')) {
  87059. $phpVersionOperator = new VersionComparisonOperator($fileNode->getAttribute('phpVersionOperator'));
  87060. }
  87061. $files[] = new TestFile($this->toAbsolutePath($filename, $file), $phpVersion, $phpVersionOperator);
  87062. }
  87063. $name = $element->getAttribute('name');
  87064. assert(!empty($name));
  87065. $testSuites[] = new TestSuiteConfiguration($name, TestDirectoryCollection::fromArray($directories), TestFileCollection::fromArray($files), FileCollection::fromArray($exclude));
  87066. }
  87067. return TestSuiteCollection::fromArray($testSuites);
  87068. }
  87069. /**
  87070. * @psalm-return list<DOMElement>
  87071. */
  87072. private function getTestSuiteElements(DOMXPath $xpath): array
  87073. {
  87074. $elements = [];
  87075. $testSuiteNodes = $xpath->query('testsuites/testsuite');
  87076. if ($testSuiteNodes->length === 0) {
  87077. $testSuiteNodes = $xpath->query('testsuite');
  87078. }
  87079. if ($testSuiteNodes->length === 1) {
  87080. $element = $testSuiteNodes->item(0);
  87081. assert($element instanceof DOMElement);
  87082. $elements[] = $element;
  87083. } else {
  87084. foreach ($testSuiteNodes as $testSuiteNode) {
  87085. assert($testSuiteNode instanceof DOMElement);
  87086. $elements[] = $testSuiteNode;
  87087. }
  87088. }
  87089. return $elements;
  87090. }
  87091. private function element(DOMXPath $xpath, string $element): ?DOMElement
  87092. {
  87093. $nodes = $xpath->query($element);
  87094. if ($nodes->length === 1) {
  87095. $node = $nodes->item(0);
  87096. assert($node instanceof DOMElement);
  87097. return $node;
  87098. }
  87099. return null;
  87100. }
  87101. }
  87102. <?php
  87103. declare (strict_types=1);
  87104. /*
  87105. * This file is part of PHPUnit.
  87106. *
  87107. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87108. *
  87109. * For the full copyright and license information, please view the LICENSE
  87110. * file that was distributed with this source code.
  87111. */
  87112. namespace PHPUnit\TextUI\XmlConfiguration\Logging;
  87113. use PHPUnit\TextUI\Configuration\File;
  87114. /**
  87115. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87116. *
  87117. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87118. *
  87119. * @psalm-immutable
  87120. */
  87121. final class Junit
  87122. {
  87123. private readonly File $target;
  87124. public function __construct(File $target)
  87125. {
  87126. $this->target = $target;
  87127. }
  87128. public function target(): File
  87129. {
  87130. return $this->target;
  87131. }
  87132. }
  87133. <?php
  87134. declare (strict_types=1);
  87135. /*
  87136. * This file is part of PHPUnit.
  87137. *
  87138. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87139. *
  87140. * For the full copyright and license information, please view the LICENSE
  87141. * file that was distributed with this source code.
  87142. */
  87143. namespace PHPUnit\TextUI\XmlConfiguration\Logging;
  87144. use PHPUnit\TextUI\XmlConfiguration\Exception;
  87145. use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml;
  87146. use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText;
  87147. /**
  87148. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87149. *
  87150. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87151. *
  87152. * @psalm-immutable
  87153. */
  87154. final class Logging
  87155. {
  87156. private readonly ?\PHPUnit\TextUI\XmlConfiguration\Logging\Junit $junit;
  87157. private readonly ?\PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity $teamCity;
  87158. private readonly ?TestDoxHtml $testDoxHtml;
  87159. private readonly ?TestDoxText $testDoxText;
  87160. public function __construct(?\PHPUnit\TextUI\XmlConfiguration\Logging\Junit $junit, ?\PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity $teamCity, ?TestDoxHtml $testDoxHtml, ?TestDoxText $testDoxText)
  87161. {
  87162. $this->junit = $junit;
  87163. $this->teamCity = $teamCity;
  87164. $this->testDoxHtml = $testDoxHtml;
  87165. $this->testDoxText = $testDoxText;
  87166. }
  87167. public function hasJunit(): bool
  87168. {
  87169. return $this->junit !== null;
  87170. }
  87171. /**
  87172. * @throws Exception
  87173. */
  87174. public function junit(): \PHPUnit\TextUI\XmlConfiguration\Logging\Junit
  87175. {
  87176. if ($this->junit === null) {
  87177. throw new Exception('Logger "JUnit XML" is not configured');
  87178. }
  87179. return $this->junit;
  87180. }
  87181. public function hasTeamCity(): bool
  87182. {
  87183. return $this->teamCity !== null;
  87184. }
  87185. /**
  87186. * @throws Exception
  87187. */
  87188. public function teamCity(): \PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity
  87189. {
  87190. if ($this->teamCity === null) {
  87191. throw new Exception('Logger "Team City" is not configured');
  87192. }
  87193. return $this->teamCity;
  87194. }
  87195. public function hasTestDoxHtml(): bool
  87196. {
  87197. return $this->testDoxHtml !== null;
  87198. }
  87199. /**
  87200. * @throws Exception
  87201. */
  87202. public function testDoxHtml(): TestDoxHtml
  87203. {
  87204. if ($this->testDoxHtml === null) {
  87205. throw new Exception('Logger "TestDox HTML" is not configured');
  87206. }
  87207. return $this->testDoxHtml;
  87208. }
  87209. public function hasTestDoxText(): bool
  87210. {
  87211. return $this->testDoxText !== null;
  87212. }
  87213. /**
  87214. * @throws Exception
  87215. */
  87216. public function testDoxText(): TestDoxText
  87217. {
  87218. if ($this->testDoxText === null) {
  87219. throw new Exception('Logger "TestDox Text" is not configured');
  87220. }
  87221. return $this->testDoxText;
  87222. }
  87223. }
  87224. <?php
  87225. declare (strict_types=1);
  87226. /*
  87227. * This file is part of PHPUnit.
  87228. *
  87229. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87230. *
  87231. * For the full copyright and license information, please view the LICENSE
  87232. * file that was distributed with this source code.
  87233. */
  87234. namespace PHPUnit\TextUI\XmlConfiguration\Logging;
  87235. use PHPUnit\TextUI\Configuration\File;
  87236. /**
  87237. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87238. *
  87239. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87240. *
  87241. * @psalm-immutable
  87242. */
  87243. final class TeamCity
  87244. {
  87245. private readonly File $target;
  87246. public function __construct(File $target)
  87247. {
  87248. $this->target = $target;
  87249. }
  87250. public function target(): File
  87251. {
  87252. return $this->target;
  87253. }
  87254. }
  87255. <?php
  87256. declare (strict_types=1);
  87257. /*
  87258. * This file is part of PHPUnit.
  87259. *
  87260. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87261. *
  87262. * For the full copyright and license information, please view the LICENSE
  87263. * file that was distributed with this source code.
  87264. */
  87265. namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox;
  87266. use PHPUnit\TextUI\Configuration\File;
  87267. /**
  87268. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87269. *
  87270. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87271. *
  87272. * @psalm-immutable
  87273. */
  87274. final class Html
  87275. {
  87276. private readonly File $target;
  87277. public function __construct(File $target)
  87278. {
  87279. $this->target = $target;
  87280. }
  87281. public function target(): File
  87282. {
  87283. return $this->target;
  87284. }
  87285. }
  87286. <?php
  87287. declare (strict_types=1);
  87288. /*
  87289. * This file is part of PHPUnit.
  87290. *
  87291. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87292. *
  87293. * For the full copyright and license information, please view the LICENSE
  87294. * file that was distributed with this source code.
  87295. */
  87296. namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox;
  87297. use PHPUnit\TextUI\Configuration\File;
  87298. /**
  87299. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87300. *
  87301. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87302. *
  87303. * @psalm-immutable
  87304. */
  87305. final class Text
  87306. {
  87307. private readonly File $target;
  87308. public function __construct(File $target)
  87309. {
  87310. $this->target = $target;
  87311. }
  87312. public function target(): File
  87313. {
  87314. return $this->target;
  87315. }
  87316. }
  87317. <?php
  87318. declare (strict_types=1);
  87319. /*
  87320. * This file is part of PHPUnit.
  87321. *
  87322. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87323. *
  87324. * For the full copyright and license information, please view the LICENSE
  87325. * file that was distributed with this source code.
  87326. */
  87327. namespace PHPUnit\TextUI\XmlConfiguration;
  87328. use function version_compare;
  87329. /**
  87330. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87331. *
  87332. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87333. */
  87334. final class MigrationBuilder
  87335. {
  87336. private const AVAILABLE_MIGRATIONS = ['8.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveLogTypes::class], '9.2' => [\PHPUnit\TextUI\XmlConfiguration\RemoveCacheTokensAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCoverageElement::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromRootToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromFilterWhitelistToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistIncludesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistExcludesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\RemoveEmptyFilter::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCloverToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCrap4jToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageHtmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoveragePhpToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageTextToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageXmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\ConvertLogTypes::class], '9.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveListeners::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestSuiteLoaderAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCacheResultFileAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementProcessUncoveredFilesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBackupStaticAttributesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemovePrinterAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveVerboseAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameForceCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBeStrictAboutCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveConversionToExceptionsAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveNoInteractionAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveLoggingElements::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestDoxGroupsElement::class], '10.0' => [\PHPUnit\TextUI\XmlConfiguration\MoveCoverageDirectoriesToSource::class], '10.4' => [\PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class]];
  87337. public function build(string $fromVersion): array
  87338. {
  87339. $stack = [new \PHPUnit\TextUI\XmlConfiguration\UpdateSchemaLocation()];
  87340. foreach (self::AVAILABLE_MIGRATIONS as $version => $migrations) {
  87341. if (version_compare($version, $fromVersion, '<')) {
  87342. continue;
  87343. }
  87344. foreach ($migrations as $migration) {
  87345. $stack[] = new $migration();
  87346. }
  87347. }
  87348. return $stack;
  87349. }
  87350. }
  87351. <?php
  87352. declare (strict_types=1);
  87353. /*
  87354. * This file is part of PHPUnit.
  87355. *
  87356. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87357. *
  87358. * For the full copyright and license information, please view the LICENSE
  87359. * file that was distributed with this source code.
  87360. */
  87361. namespace PHPUnit\TextUI\XmlConfiguration;
  87362. use PHPUnit\Exception;
  87363. use RuntimeException;
  87364. /**
  87365. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87366. *
  87367. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87368. */
  87369. final class MigrationException extends RuntimeException implements Exception
  87370. {
  87371. }
  87372. <?php
  87373. declare (strict_types=1);
  87374. /*
  87375. * This file is part of PHPUnit.
  87376. *
  87377. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87378. *
  87379. * For the full copyright and license information, please view the LICENSE
  87380. * file that was distributed with this source code.
  87381. */
  87382. namespace PHPUnit\TextUI\XmlConfiguration;
  87383. use DOMDocument;
  87384. use DOMElement;
  87385. /**
  87386. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87387. *
  87388. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87389. */
  87390. final class ConvertLogTypes implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87391. {
  87392. public function migrate(DOMDocument $document): void
  87393. {
  87394. $logging = $document->getElementsByTagName('logging')->item(0);
  87395. if (!$logging instanceof DOMElement) {
  87396. return;
  87397. }
  87398. $types = ['junit' => 'junit', 'teamcity' => 'teamcity', 'testdox-html' => 'testdoxHtml', 'testdox-text' => 'testdoxText', 'testdox-xml' => 'testdoxXml', 'plain' => 'text'];
  87399. $logNodes = [];
  87400. foreach ($logging->getElementsByTagName('log') as $logNode) {
  87401. if (!isset($types[$logNode->getAttribute('type')])) {
  87402. continue;
  87403. }
  87404. $logNodes[] = $logNode;
  87405. }
  87406. foreach ($logNodes as $oldNode) {
  87407. $newLogNode = $document->createElement($types[$oldNode->getAttribute('type')]);
  87408. $newLogNode->setAttribute('outputFile', $oldNode->getAttribute('target'));
  87409. $logging->replaceChild($newLogNode, $oldNode);
  87410. }
  87411. }
  87412. }
  87413. <?php
  87414. declare (strict_types=1);
  87415. /*
  87416. * This file is part of PHPUnit.
  87417. *
  87418. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87419. *
  87420. * For the full copyright and license information, please view the LICENSE
  87421. * file that was distributed with this source code.
  87422. */
  87423. namespace PHPUnit\TextUI\XmlConfiguration;
  87424. use DOMElement;
  87425. /**
  87426. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87427. *
  87428. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87429. */
  87430. final class CoverageCloverToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87431. {
  87432. protected function forType(): string
  87433. {
  87434. return 'coverage-clover';
  87435. }
  87436. protected function toReportFormat(DOMElement $logNode): DOMElement
  87437. {
  87438. $clover = $logNode->ownerDocument->createElement('clover');
  87439. $clover->setAttribute('outputFile', $logNode->getAttribute('target'));
  87440. return $clover;
  87441. }
  87442. }
  87443. <?php
  87444. declare (strict_types=1);
  87445. /*
  87446. * This file is part of PHPUnit.
  87447. *
  87448. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87449. *
  87450. * For the full copyright and license information, please view the LICENSE
  87451. * file that was distributed with this source code.
  87452. */
  87453. namespace PHPUnit\TextUI\XmlConfiguration;
  87454. use DOMElement;
  87455. /**
  87456. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87457. *
  87458. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87459. */
  87460. final class CoverageCrap4jToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87461. {
  87462. protected function forType(): string
  87463. {
  87464. return 'coverage-crap4j';
  87465. }
  87466. protected function toReportFormat(DOMElement $logNode): DOMElement
  87467. {
  87468. $crap4j = $logNode->ownerDocument->createElement('crap4j');
  87469. $crap4j->setAttribute('outputFile', $logNode->getAttribute('target'));
  87470. $this->migrateAttributes($logNode, $crap4j, ['threshold']);
  87471. return $crap4j;
  87472. }
  87473. }
  87474. <?php
  87475. declare (strict_types=1);
  87476. /*
  87477. * This file is part of PHPUnit.
  87478. *
  87479. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87480. *
  87481. * For the full copyright and license information, please view the LICENSE
  87482. * file that was distributed with this source code.
  87483. */
  87484. namespace PHPUnit\TextUI\XmlConfiguration;
  87485. use DOMElement;
  87486. /**
  87487. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87488. *
  87489. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87490. */
  87491. final class CoverageHtmlToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87492. {
  87493. protected function forType(): string
  87494. {
  87495. return 'coverage-html';
  87496. }
  87497. protected function toReportFormat(DOMElement $logNode): DOMElement
  87498. {
  87499. $html = $logNode->ownerDocument->createElement('html');
  87500. $html->setAttribute('outputDirectory', $logNode->getAttribute('target'));
  87501. $this->migrateAttributes($logNode, $html, ['lowUpperBound', 'highLowerBound']);
  87502. return $html;
  87503. }
  87504. }
  87505. <?php
  87506. declare (strict_types=1);
  87507. /*
  87508. * This file is part of PHPUnit.
  87509. *
  87510. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87511. *
  87512. * For the full copyright and license information, please view the LICENSE
  87513. * file that was distributed with this source code.
  87514. */
  87515. namespace PHPUnit\TextUI\XmlConfiguration;
  87516. use DOMElement;
  87517. /**
  87518. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87519. *
  87520. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87521. */
  87522. final class CoveragePhpToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87523. {
  87524. protected function forType(): string
  87525. {
  87526. return 'coverage-php';
  87527. }
  87528. protected function toReportFormat(DOMElement $logNode): DOMElement
  87529. {
  87530. $php = $logNode->ownerDocument->createElement('php');
  87531. $php->setAttribute('outputFile', $logNode->getAttribute('target'));
  87532. return $php;
  87533. }
  87534. }
  87535. <?php
  87536. declare (strict_types=1);
  87537. /*
  87538. * This file is part of PHPUnit.
  87539. *
  87540. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87541. *
  87542. * For the full copyright and license information, please view the LICENSE
  87543. * file that was distributed with this source code.
  87544. */
  87545. namespace PHPUnit\TextUI\XmlConfiguration;
  87546. use DOMElement;
  87547. /**
  87548. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87549. *
  87550. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87551. */
  87552. final class CoverageTextToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87553. {
  87554. protected function forType(): string
  87555. {
  87556. return 'coverage-text';
  87557. }
  87558. protected function toReportFormat(DOMElement $logNode): DOMElement
  87559. {
  87560. $text = $logNode->ownerDocument->createElement('text');
  87561. $text->setAttribute('outputFile', $logNode->getAttribute('target'));
  87562. $this->migrateAttributes($logNode, $text, ['showUncoveredFiles', 'showOnlySummary']);
  87563. return $text;
  87564. }
  87565. }
  87566. <?php
  87567. declare (strict_types=1);
  87568. /*
  87569. * This file is part of PHPUnit.
  87570. *
  87571. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87572. *
  87573. * For the full copyright and license information, please view the LICENSE
  87574. * file that was distributed with this source code.
  87575. */
  87576. namespace PHPUnit\TextUI\XmlConfiguration;
  87577. use DOMElement;
  87578. /**
  87579. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87580. *
  87581. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87582. */
  87583. final class CoverageXmlToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
  87584. {
  87585. protected function forType(): string
  87586. {
  87587. return 'coverage-xml';
  87588. }
  87589. protected function toReportFormat(DOMElement $logNode): DOMElement
  87590. {
  87591. $xml = $logNode->ownerDocument->createElement('xml');
  87592. $xml->setAttribute('outputDirectory', $logNode->getAttribute('target'));
  87593. return $xml;
  87594. }
  87595. }
  87596. <?php
  87597. declare (strict_types=1);
  87598. /*
  87599. * This file is part of PHPUnit.
  87600. *
  87601. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87602. *
  87603. * For the full copyright and license information, please view the LICENSE
  87604. * file that was distributed with this source code.
  87605. */
  87606. namespace PHPUnit\TextUI\XmlConfiguration;
  87607. use function assert;
  87608. use DOMDocument;
  87609. use DOMElement;
  87610. /**
  87611. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87612. *
  87613. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87614. */
  87615. final class IntroduceCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87616. {
  87617. public function migrate(DOMDocument $document): void
  87618. {
  87619. $root = $document->documentElement;
  87620. assert($root instanceof DOMElement);
  87621. if ($root->hasAttribute('cacheDirectory')) {
  87622. return;
  87623. }
  87624. $root->setAttribute('cacheDirectory', '.phpunit.cache');
  87625. }
  87626. }
  87627. <?php
  87628. declare (strict_types=1);
  87629. /*
  87630. * This file is part of PHPUnit.
  87631. *
  87632. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87633. *
  87634. * For the full copyright and license information, please view the LICENSE
  87635. * file that was distributed with this source code.
  87636. */
  87637. namespace PHPUnit\TextUI\XmlConfiguration;
  87638. use DOMDocument;
  87639. /**
  87640. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87641. *
  87642. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87643. */
  87644. final class IntroduceCoverageElement implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87645. {
  87646. public function migrate(DOMDocument $document): void
  87647. {
  87648. $coverage = $document->createElement('coverage');
  87649. $document->documentElement->insertBefore($coverage, $document->documentElement->firstChild);
  87650. }
  87651. }
  87652. <?php
  87653. declare (strict_types=1);
  87654. /*
  87655. * This file is part of PHPUnit.
  87656. *
  87657. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87658. *
  87659. * For the full copyright and license information, please view the LICENSE
  87660. * file that was distributed with this source code.
  87661. */
  87662. namespace PHPUnit\TextUI\XmlConfiguration;
  87663. use function sprintf;
  87664. use DOMDocument;
  87665. use DOMElement;
  87666. use DOMXPath;
  87667. /**
  87668. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87669. *
  87670. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87671. */
  87672. abstract class LogToReportMigration implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87673. {
  87674. /**
  87675. * @throws MigrationException
  87676. */
  87677. public function migrate(DOMDocument $document): void
  87678. {
  87679. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87680. if (!$coverage instanceof DOMElement) {
  87681. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
  87682. }
  87683. $logNode = $this->findLogNode($document);
  87684. if ($logNode === null) {
  87685. return;
  87686. }
  87687. $reportChild = $this->toReportFormat($logNode);
  87688. $report = $coverage->getElementsByTagName('report')->item(0);
  87689. if ($report === null) {
  87690. $report = $coverage->appendChild($document->createElement('report'));
  87691. }
  87692. $report->appendChild($reportChild);
  87693. $logNode->parentNode->removeChild($logNode);
  87694. }
  87695. protected function migrateAttributes(DOMElement $src, DOMElement $dest, array $attributes): void
  87696. {
  87697. foreach ($attributes as $attr) {
  87698. if (!$src->hasAttribute($attr)) {
  87699. continue;
  87700. }
  87701. $dest->setAttribute($attr, $src->getAttribute($attr));
  87702. $src->removeAttribute($attr);
  87703. }
  87704. }
  87705. abstract protected function forType(): string;
  87706. abstract protected function toReportFormat(DOMElement $logNode): DOMElement;
  87707. private function findLogNode(DOMDocument $document): ?DOMElement
  87708. {
  87709. $logNode = (new DOMXPath($document))->query(sprintf('//logging/log[@type="%s"]', $this->forType()))->item(0);
  87710. if (!$logNode instanceof DOMElement) {
  87711. return null;
  87712. }
  87713. return $logNode;
  87714. }
  87715. }
  87716. <?php
  87717. declare (strict_types=1);
  87718. /*
  87719. * This file is part of PHPUnit.
  87720. *
  87721. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87722. *
  87723. * For the full copyright and license information, please view the LICENSE
  87724. * file that was distributed with this source code.
  87725. */
  87726. namespace PHPUnit\TextUI\XmlConfiguration;
  87727. use DOMDocument;
  87728. /**
  87729. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87730. *
  87731. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87732. */
  87733. interface Migration
  87734. {
  87735. public function migrate(DOMDocument $document): void;
  87736. }
  87737. <?php
  87738. declare (strict_types=1);
  87739. /*
  87740. * This file is part of PHPUnit.
  87741. *
  87742. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87743. *
  87744. * For the full copyright and license information, please view the LICENSE
  87745. * file that was distributed with this source code.
  87746. */
  87747. namespace PHPUnit\TextUI\XmlConfiguration;
  87748. use DOMDocument;
  87749. use DOMElement;
  87750. /**
  87751. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87752. *
  87753. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87754. */
  87755. final class MoveAttributesFromFilterWhitelistToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87756. {
  87757. /**
  87758. * @throws MigrationException
  87759. */
  87760. public function migrate(DOMDocument $document): void
  87761. {
  87762. $whitelist = $document->getElementsByTagName('whitelist')->item(0);
  87763. if (!$whitelist) {
  87764. return;
  87765. }
  87766. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87767. if (!$coverage instanceof DOMElement) {
  87768. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
  87769. }
  87770. $map = ['addUncoveredFilesFromWhitelist' => 'includeUncoveredFiles', 'processUncoveredFilesFromWhitelist' => 'processUncoveredFiles'];
  87771. foreach ($map as $old => $new) {
  87772. if (!$whitelist->hasAttribute($old)) {
  87773. continue;
  87774. }
  87775. $coverage->setAttribute($new, $whitelist->getAttribute($old));
  87776. $whitelist->removeAttribute($old);
  87777. }
  87778. }
  87779. }
  87780. <?php
  87781. declare (strict_types=1);
  87782. /*
  87783. * This file is part of PHPUnit.
  87784. *
  87785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87786. *
  87787. * For the full copyright and license information, please view the LICENSE
  87788. * file that was distributed with this source code.
  87789. */
  87790. namespace PHPUnit\TextUI\XmlConfiguration;
  87791. use function assert;
  87792. use DOMDocument;
  87793. use DOMElement;
  87794. /**
  87795. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87796. *
  87797. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87798. */
  87799. final class MoveAttributesFromRootToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87800. {
  87801. /**
  87802. * @throws MigrationException
  87803. */
  87804. public function migrate(DOMDocument $document): void
  87805. {
  87806. $map = ['disableCodeCoverageIgnore' => 'disableCodeCoverageIgnore', 'ignoreDeprecatedCodeUnitsFromCodeCoverage' => 'ignoreDeprecatedCodeUnits'];
  87807. $root = $document->documentElement;
  87808. assert($root instanceof DOMElement);
  87809. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87810. if (!$coverage instanceof DOMElement) {
  87811. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
  87812. }
  87813. foreach ($map as $old => $new) {
  87814. if (!$root->hasAttribute($old)) {
  87815. continue;
  87816. }
  87817. $coverage->setAttribute($new, $root->getAttribute($old));
  87818. $root->removeAttribute($old);
  87819. }
  87820. }
  87821. }
  87822. <?php
  87823. declare (strict_types=1);
  87824. /*
  87825. * This file is part of PHPUnit.
  87826. *
  87827. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87828. *
  87829. * For the full copyright and license information, please view the LICENSE
  87830. * file that was distributed with this source code.
  87831. */
  87832. namespace PHPUnit\TextUI\XmlConfiguration;
  87833. use function assert;
  87834. use DOMDocument;
  87835. use DOMElement;
  87836. use DOMXPath;
  87837. /**
  87838. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87839. *
  87840. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87841. */
  87842. final class MoveCoverageDirectoriesToSource implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87843. {
  87844. /**
  87845. * @throws MigrationException
  87846. */
  87847. public function migrate(DOMDocument $document): void
  87848. {
  87849. $source = $document->getElementsByTagName('source')->item(0);
  87850. if ($source !== null) {
  87851. return;
  87852. }
  87853. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87854. if ($coverage === null) {
  87855. return;
  87856. }
  87857. $root = $document->documentElement;
  87858. assert($root instanceof DOMElement);
  87859. $source = $document->createElement('source');
  87860. $root->appendChild($source);
  87861. $xpath = new DOMXPath($document);
  87862. foreach (['include', 'exclude'] as $element) {
  87863. foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($xpath->query('//coverage/' . $element)) as $node) {
  87864. $source->appendChild($node);
  87865. }
  87866. }
  87867. if ($coverage->childElementCount !== 0) {
  87868. return;
  87869. }
  87870. assert($coverage->parentNode !== null);
  87871. $coverage->parentNode->removeChild($coverage);
  87872. }
  87873. }
  87874. <?php
  87875. declare (strict_types=1);
  87876. /*
  87877. * This file is part of PHPUnit.
  87878. *
  87879. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87880. *
  87881. * For the full copyright and license information, please view the LICENSE
  87882. * file that was distributed with this source code.
  87883. */
  87884. namespace PHPUnit\TextUI\XmlConfiguration;
  87885. use function assert;
  87886. use function in_array;
  87887. use DOMDocument;
  87888. use DOMElement;
  87889. /**
  87890. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87891. *
  87892. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87893. */
  87894. final class MoveWhitelistExcludesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87895. {
  87896. /**
  87897. * @throws MigrationException
  87898. */
  87899. public function migrate(DOMDocument $document): void
  87900. {
  87901. $whitelist = $document->getElementsByTagName('whitelist')->item(0);
  87902. if ($whitelist === null) {
  87903. return;
  87904. }
  87905. $excludeNodes = \PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->getElementsByTagName('exclude'));
  87906. if ($excludeNodes->count() === 0) {
  87907. return;
  87908. }
  87909. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87910. if (!$coverage instanceof DOMElement) {
  87911. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
  87912. }
  87913. $targetExclude = $coverage->getElementsByTagName('exclude')->item(0);
  87914. if ($targetExclude === null) {
  87915. $targetExclude = $coverage->appendChild($document->createElement('exclude'));
  87916. }
  87917. foreach ($excludeNodes as $excludeNode) {
  87918. assert($excludeNode instanceof DOMElement);
  87919. foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($excludeNode->childNodes) as $child) {
  87920. if (!$child instanceof DOMElement || !in_array($child->nodeName, ['directory', 'file'], \true)) {
  87921. continue;
  87922. }
  87923. $targetExclude->appendChild($child);
  87924. }
  87925. if ($excludeNode->getElementsByTagName('*')->count() !== 0) {
  87926. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Dangling child elements in exclude found.');
  87927. }
  87928. $whitelist->removeChild($excludeNode);
  87929. }
  87930. }
  87931. }
  87932. <?php
  87933. declare (strict_types=1);
  87934. /*
  87935. * This file is part of PHPUnit.
  87936. *
  87937. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87938. *
  87939. * For the full copyright and license information, please view the LICENSE
  87940. * file that was distributed with this source code.
  87941. */
  87942. namespace PHPUnit\TextUI\XmlConfiguration;
  87943. use DOMDocument;
  87944. use DOMElement;
  87945. /**
  87946. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87947. *
  87948. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87949. */
  87950. final class MoveWhitelistIncludesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87951. {
  87952. /**
  87953. * @throws MigrationException
  87954. */
  87955. public function migrate(DOMDocument $document): void
  87956. {
  87957. $whitelist = $document->getElementsByTagName('whitelist')->item(0);
  87958. if ($whitelist === null) {
  87959. return;
  87960. }
  87961. $coverage = $document->getElementsByTagName('coverage')->item(0);
  87962. if (!$coverage instanceof DOMElement) {
  87963. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
  87964. }
  87965. $include = $document->createElement('include');
  87966. $coverage->appendChild($include);
  87967. foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->childNodes) as $child) {
  87968. if (!$child instanceof DOMElement) {
  87969. continue;
  87970. }
  87971. if (!($child->nodeName === 'directory' || $child->nodeName === 'file')) {
  87972. continue;
  87973. }
  87974. $include->appendChild($child);
  87975. }
  87976. }
  87977. }
  87978. <?php
  87979. declare (strict_types=1);
  87980. /*
  87981. * This file is part of PHPUnit.
  87982. *
  87983. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  87984. *
  87985. * For the full copyright and license information, please view the LICENSE
  87986. * file that was distributed with this source code.
  87987. */
  87988. namespace PHPUnit\TextUI\XmlConfiguration;
  87989. use function assert;
  87990. use DOMDocument;
  87991. use DOMElement;
  87992. /**
  87993. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  87994. *
  87995. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  87996. */
  87997. final class RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  87998. {
  87999. public function migrate(DOMDocument $document): void
  88000. {
  88001. $root = $document->documentElement;
  88002. assert($root instanceof DOMElement);
  88003. if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) {
  88004. $root->removeAttribute('beStrictAboutResourceUsageDuringSmallTests');
  88005. }
  88006. }
  88007. }
  88008. <?php
  88009. declare (strict_types=1);
  88010. /*
  88011. * This file is part of PHPUnit.
  88012. *
  88013. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88014. *
  88015. * For the full copyright and license information, please view the LICENSE
  88016. * file that was distributed with this source code.
  88017. */
  88018. namespace PHPUnit\TextUI\XmlConfiguration;
  88019. use function assert;
  88020. use DOMDocument;
  88021. use DOMElement;
  88022. /**
  88023. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88024. *
  88025. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88026. */
  88027. final class RemoveBeStrictAboutTodoAnnotatedTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88028. {
  88029. public function migrate(DOMDocument $document): void
  88030. {
  88031. $root = $document->documentElement;
  88032. assert($root instanceof DOMElement);
  88033. if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
  88034. $root->removeAttribute('beStrictAboutTodoAnnotatedTests');
  88035. }
  88036. }
  88037. }
  88038. <?php
  88039. declare (strict_types=1);
  88040. /*
  88041. * This file is part of PHPUnit.
  88042. *
  88043. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88044. *
  88045. * For the full copyright and license information, please view the LICENSE
  88046. * file that was distributed with this source code.
  88047. */
  88048. namespace PHPUnit\TextUI\XmlConfiguration;
  88049. use function assert;
  88050. use DOMDocument;
  88051. use DOMElement;
  88052. /**
  88053. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88054. *
  88055. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88056. */
  88057. final class RemoveCacheResultFileAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88058. {
  88059. public function migrate(DOMDocument $document): void
  88060. {
  88061. $root = $document->documentElement;
  88062. assert($root instanceof DOMElement);
  88063. if ($root->hasAttribute('cacheResultFile')) {
  88064. $root->removeAttribute('cacheResultFile');
  88065. }
  88066. }
  88067. }
  88068. <?php
  88069. declare (strict_types=1);
  88070. /*
  88071. * This file is part of PHPUnit.
  88072. *
  88073. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88074. *
  88075. * For the full copyright and license information, please view the LICENSE
  88076. * file that was distributed with this source code.
  88077. */
  88078. namespace PHPUnit\TextUI\XmlConfiguration;
  88079. use function assert;
  88080. use DOMDocument;
  88081. use DOMElement;
  88082. /**
  88083. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88084. *
  88085. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88086. */
  88087. final class RemoveCacheTokensAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88088. {
  88089. public function migrate(DOMDocument $document): void
  88090. {
  88091. $root = $document->documentElement;
  88092. assert($root instanceof DOMElement);
  88093. if ($root->hasAttribute('cacheTokens')) {
  88094. $root->removeAttribute('cacheTokens');
  88095. }
  88096. }
  88097. }
  88098. <?php
  88099. declare (strict_types=1);
  88100. /*
  88101. * This file is part of PHPUnit.
  88102. *
  88103. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88104. *
  88105. * For the full copyright and license information, please view the LICENSE
  88106. * file that was distributed with this source code.
  88107. */
  88108. namespace PHPUnit\TextUI\XmlConfiguration;
  88109. use function assert;
  88110. use DOMDocument;
  88111. use DOMElement;
  88112. /**
  88113. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88114. *
  88115. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88116. */
  88117. final class RemoveConversionToExceptionsAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88118. {
  88119. public function migrate(DOMDocument $document): void
  88120. {
  88121. $root = $document->documentElement;
  88122. assert($root instanceof DOMElement);
  88123. if ($root->hasAttribute('convertDeprecationsToExceptions')) {
  88124. $root->removeAttribute('convertDeprecationsToExceptions');
  88125. }
  88126. if ($root->hasAttribute('convertErrorsToExceptions')) {
  88127. $root->removeAttribute('convertErrorsToExceptions');
  88128. }
  88129. if ($root->hasAttribute('convertNoticesToExceptions')) {
  88130. $root->removeAttribute('convertNoticesToExceptions');
  88131. }
  88132. if ($root->hasAttribute('convertWarningsToExceptions')) {
  88133. $root->removeAttribute('convertWarningsToExceptions');
  88134. }
  88135. }
  88136. }
  88137. <?php
  88138. declare (strict_types=1);
  88139. /*
  88140. * This file is part of PHPUnit.
  88141. *
  88142. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88143. *
  88144. * For the full copyright and license information, please view the LICENSE
  88145. * file that was distributed with this source code.
  88146. */
  88147. namespace PHPUnit\TextUI\XmlConfiguration;
  88148. use DOMDocument;
  88149. use DOMElement;
  88150. /**
  88151. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88152. *
  88153. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88154. */
  88155. final class RemoveCoverageElementCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88156. {
  88157. public function migrate(DOMDocument $document): void
  88158. {
  88159. $node = $document->getElementsByTagName('coverage')->item(0);
  88160. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88161. return;
  88162. }
  88163. if ($node->hasAttribute('cacheDirectory')) {
  88164. $node->removeAttribute('cacheDirectory');
  88165. }
  88166. }
  88167. }
  88168. <?php
  88169. declare (strict_types=1);
  88170. /*
  88171. * This file is part of PHPUnit.
  88172. *
  88173. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88174. *
  88175. * For the full copyright and license information, please view the LICENSE
  88176. * file that was distributed with this source code.
  88177. */
  88178. namespace PHPUnit\TextUI\XmlConfiguration;
  88179. use DOMDocument;
  88180. use DOMElement;
  88181. /**
  88182. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88183. *
  88184. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88185. */
  88186. final class RemoveCoverageElementProcessUncoveredFilesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88187. {
  88188. public function migrate(DOMDocument $document): void
  88189. {
  88190. $node = $document->getElementsByTagName('coverage')->item(0);
  88191. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88192. return;
  88193. }
  88194. if ($node->hasAttribute('processUncoveredFiles')) {
  88195. $node->removeAttribute('processUncoveredFiles');
  88196. }
  88197. }
  88198. }
  88199. <?php
  88200. declare (strict_types=1);
  88201. /*
  88202. * This file is part of PHPUnit.
  88203. *
  88204. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88205. *
  88206. * For the full copyright and license information, please view the LICENSE
  88207. * file that was distributed with this source code.
  88208. */
  88209. namespace PHPUnit\TextUI\XmlConfiguration;
  88210. use function sprintf;
  88211. use DOMDocument;
  88212. use DOMElement;
  88213. /**
  88214. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88215. *
  88216. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88217. */
  88218. final class RemoveEmptyFilter implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88219. {
  88220. /**
  88221. * @throws MigrationException
  88222. */
  88223. public function migrate(DOMDocument $document): void
  88224. {
  88225. $whitelist = $document->getElementsByTagName('whitelist')->item(0);
  88226. if ($whitelist instanceof DOMElement) {
  88227. $this->ensureEmpty($whitelist);
  88228. $whitelist->parentNode->removeChild($whitelist);
  88229. }
  88230. $filter = $document->getElementsByTagName('filter')->item(0);
  88231. if ($filter instanceof DOMElement) {
  88232. $this->ensureEmpty($filter);
  88233. $filter->parentNode->removeChild($filter);
  88234. }
  88235. }
  88236. /**
  88237. * @throws MigrationException
  88238. */
  88239. private function ensureEmpty(DOMElement $element): void
  88240. {
  88241. if ($element->attributes->length > 0) {
  88242. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected attributes', $element->nodeName));
  88243. }
  88244. if ($element->getElementsByTagName('*')->length > 0) {
  88245. throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected children', $element->nodeName));
  88246. }
  88247. }
  88248. }
  88249. <?php
  88250. declare (strict_types=1);
  88251. /*
  88252. * This file is part of PHPUnit.
  88253. *
  88254. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88255. *
  88256. * For the full copyright and license information, please view the LICENSE
  88257. * file that was distributed with this source code.
  88258. */
  88259. namespace PHPUnit\TextUI\XmlConfiguration;
  88260. use DOMDocument;
  88261. use DOMElement;
  88262. /**
  88263. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88264. *
  88265. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88266. */
  88267. final class RemoveListeners implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88268. {
  88269. public function migrate(DOMDocument $document): void
  88270. {
  88271. $node = $document->getElementsByTagName('listeners')->item(0);
  88272. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88273. return;
  88274. }
  88275. $node->parentNode->removeChild($node);
  88276. }
  88277. }
  88278. <?php
  88279. declare (strict_types=1);
  88280. /*
  88281. * This file is part of PHPUnit.
  88282. *
  88283. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88284. *
  88285. * For the full copyright and license information, please view the LICENSE
  88286. * file that was distributed with this source code.
  88287. */
  88288. namespace PHPUnit\TextUI\XmlConfiguration;
  88289. use function assert;
  88290. use DOMDocument;
  88291. use DOMElement;
  88292. /**
  88293. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88294. *
  88295. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88296. */
  88297. final class RemoveLogTypes implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88298. {
  88299. public function migrate(DOMDocument $document): void
  88300. {
  88301. $logging = $document->getElementsByTagName('logging')->item(0);
  88302. if (!$logging instanceof DOMElement) {
  88303. return;
  88304. }
  88305. foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($logging->getElementsByTagName('log')) as $logNode) {
  88306. assert($logNode instanceof DOMElement);
  88307. switch ($logNode->getAttribute('type')) {
  88308. case 'json':
  88309. case 'tap':
  88310. $logging->removeChild($logNode);
  88311. }
  88312. }
  88313. }
  88314. }
  88315. <?php
  88316. declare (strict_types=1);
  88317. /*
  88318. * This file is part of PHPUnit.
  88319. *
  88320. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88321. *
  88322. * For the full copyright and license information, please view the LICENSE
  88323. * file that was distributed with this source code.
  88324. */
  88325. namespace PHPUnit\TextUI\XmlConfiguration;
  88326. use DOMDocument;
  88327. use DOMElement;
  88328. use DOMXPath;
  88329. /**
  88330. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88331. *
  88332. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88333. */
  88334. final class RemoveLoggingElements implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88335. {
  88336. public function migrate(DOMDocument $document): void
  88337. {
  88338. $this->removeTestDoxElement($document);
  88339. $this->removeTextElement($document);
  88340. }
  88341. private function removeTestDoxElement(DOMDocument $document): void
  88342. {
  88343. $node = (new DOMXPath($document))->query('logging/testdoxXml')->item(0);
  88344. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88345. return;
  88346. }
  88347. $node->parentNode->removeChild($node);
  88348. }
  88349. private function removeTextElement(DOMDocument $document): void
  88350. {
  88351. $node = (new DOMXPath($document))->query('logging/text')->item(0);
  88352. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88353. return;
  88354. }
  88355. $node->parentNode->removeChild($node);
  88356. }
  88357. }
  88358. <?php
  88359. declare (strict_types=1);
  88360. /*
  88361. * This file is part of PHPUnit.
  88362. *
  88363. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88364. *
  88365. * For the full copyright and license information, please view the LICENSE
  88366. * file that was distributed with this source code.
  88367. */
  88368. namespace PHPUnit\TextUI\XmlConfiguration;
  88369. use function assert;
  88370. use DOMDocument;
  88371. use DOMElement;
  88372. /**
  88373. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88374. *
  88375. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88376. */
  88377. final class RemoveNoInteractionAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88378. {
  88379. public function migrate(DOMDocument $document): void
  88380. {
  88381. $root = $document->documentElement;
  88382. assert($root instanceof DOMElement);
  88383. if ($root->hasAttribute('noInteraction')) {
  88384. $root->removeAttribute('noInteraction');
  88385. }
  88386. }
  88387. }
  88388. <?php
  88389. declare (strict_types=1);
  88390. /*
  88391. * This file is part of PHPUnit.
  88392. *
  88393. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88394. *
  88395. * For the full copyright and license information, please view the LICENSE
  88396. * file that was distributed with this source code.
  88397. */
  88398. namespace PHPUnit\TextUI\XmlConfiguration;
  88399. use function assert;
  88400. use DOMDocument;
  88401. use DOMElement;
  88402. /**
  88403. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88404. *
  88405. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88406. */
  88407. final class RemovePrinterAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88408. {
  88409. public function migrate(DOMDocument $document): void
  88410. {
  88411. $root = $document->documentElement;
  88412. assert($root instanceof DOMElement);
  88413. if ($root->hasAttribute('printerClass')) {
  88414. $root->removeAttribute('printerClass');
  88415. }
  88416. if ($root->hasAttribute('printerFile')) {
  88417. $root->removeAttribute('printerFile');
  88418. }
  88419. }
  88420. }
  88421. <?php
  88422. declare (strict_types=1);
  88423. /*
  88424. * This file is part of PHPUnit.
  88425. *
  88426. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88427. *
  88428. * For the full copyright and license information, please view the LICENSE
  88429. * file that was distributed with this source code.
  88430. */
  88431. namespace PHPUnit\TextUI\XmlConfiguration;
  88432. use DOMDocument;
  88433. use DOMElement;
  88434. /**
  88435. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88436. *
  88437. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88438. */
  88439. final class RemoveTestDoxGroupsElement implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88440. {
  88441. public function migrate(DOMDocument $document): void
  88442. {
  88443. $node = $document->getElementsByTagName('testdoxGroups')->item(0);
  88444. if (!$node instanceof DOMElement || $node->parentNode === null) {
  88445. return;
  88446. }
  88447. $node->parentNode->removeChild($node);
  88448. }
  88449. }
  88450. <?php
  88451. declare (strict_types=1);
  88452. /*
  88453. * This file is part of PHPUnit.
  88454. *
  88455. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88456. *
  88457. * For the full copyright and license information, please view the LICENSE
  88458. * file that was distributed with this source code.
  88459. */
  88460. namespace PHPUnit\TextUI\XmlConfiguration;
  88461. use function assert;
  88462. use DOMDocument;
  88463. use DOMElement;
  88464. /**
  88465. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88466. *
  88467. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88468. */
  88469. final class RemoveTestSuiteLoaderAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88470. {
  88471. public function migrate(DOMDocument $document): void
  88472. {
  88473. $root = $document->documentElement;
  88474. assert($root instanceof DOMElement);
  88475. if ($root->hasAttribute('testSuiteLoaderClass')) {
  88476. $root->removeAttribute('testSuiteLoaderClass');
  88477. }
  88478. if ($root->hasAttribute('testSuiteLoaderFile')) {
  88479. $root->removeAttribute('testSuiteLoaderFile');
  88480. }
  88481. }
  88482. }
  88483. <?php
  88484. declare (strict_types=1);
  88485. /*
  88486. * This file is part of PHPUnit.
  88487. *
  88488. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88489. *
  88490. * For the full copyright and license information, please view the LICENSE
  88491. * file that was distributed with this source code.
  88492. */
  88493. namespace PHPUnit\TextUI\XmlConfiguration;
  88494. use function assert;
  88495. use DOMDocument;
  88496. use DOMElement;
  88497. /**
  88498. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88499. *
  88500. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88501. */
  88502. final class RemoveVerboseAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88503. {
  88504. public function migrate(DOMDocument $document): void
  88505. {
  88506. $root = $document->documentElement;
  88507. assert($root instanceof DOMElement);
  88508. if ($root->hasAttribute('verbose')) {
  88509. $root->removeAttribute('verbose');
  88510. }
  88511. }
  88512. }
  88513. <?php
  88514. declare (strict_types=1);
  88515. /*
  88516. * This file is part of PHPUnit.
  88517. *
  88518. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88519. *
  88520. * For the full copyright and license information, please view the LICENSE
  88521. * file that was distributed with this source code.
  88522. */
  88523. namespace PHPUnit\TextUI\XmlConfiguration;
  88524. use function assert;
  88525. use DOMDocument;
  88526. use DOMElement;
  88527. /**
  88528. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88529. *
  88530. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88531. */
  88532. final class RenameBackupStaticAttributesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88533. {
  88534. public function migrate(DOMDocument $document): void
  88535. {
  88536. $root = $document->documentElement;
  88537. assert($root instanceof DOMElement);
  88538. if ($root->hasAttribute('backupStaticProperties')) {
  88539. return;
  88540. }
  88541. if (!$root->hasAttribute('backupStaticAttributes')) {
  88542. return;
  88543. }
  88544. $root->setAttribute('backupStaticProperties', $root->getAttribute('backupStaticAttributes'));
  88545. $root->removeAttribute('backupStaticAttributes');
  88546. }
  88547. }
  88548. <?php
  88549. declare (strict_types=1);
  88550. /*
  88551. * This file is part of PHPUnit.
  88552. *
  88553. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88554. *
  88555. * For the full copyright and license information, please view the LICENSE
  88556. * file that was distributed with this source code.
  88557. */
  88558. namespace PHPUnit\TextUI\XmlConfiguration;
  88559. use function assert;
  88560. use DOMDocument;
  88561. use DOMElement;
  88562. /**
  88563. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88564. *
  88565. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88566. */
  88567. final class RenameBeStrictAboutCoversAnnotationAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88568. {
  88569. public function migrate(DOMDocument $document): void
  88570. {
  88571. $root = $document->documentElement;
  88572. assert($root instanceof DOMElement);
  88573. if ($root->hasAttribute('beStrictAboutCoverageMetadata')) {
  88574. return;
  88575. }
  88576. if (!$root->hasAttribute('beStrictAboutCoversAnnotation')) {
  88577. return;
  88578. }
  88579. $root->setAttribute('beStrictAboutCoverageMetadata', $root->getAttribute('beStrictAboutCoversAnnotation'));
  88580. $root->removeAttribute('beStrictAboutCoversAnnotation');
  88581. }
  88582. }
  88583. <?php
  88584. declare (strict_types=1);
  88585. /*
  88586. * This file is part of PHPUnit.
  88587. *
  88588. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88589. *
  88590. * For the full copyright and license information, please view the LICENSE
  88591. * file that was distributed with this source code.
  88592. */
  88593. namespace PHPUnit\TextUI\XmlConfiguration;
  88594. use function assert;
  88595. use DOMDocument;
  88596. use DOMElement;
  88597. /**
  88598. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88599. *
  88600. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88601. */
  88602. final class RenameForceCoversAnnotationAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88603. {
  88604. public function migrate(DOMDocument $document): void
  88605. {
  88606. $root = $document->documentElement;
  88607. assert($root instanceof DOMElement);
  88608. if ($root->hasAttribute('requireCoverageMetadata')) {
  88609. return;
  88610. }
  88611. if (!$root->hasAttribute('forceCoversAnnotation')) {
  88612. return;
  88613. }
  88614. $root->setAttribute('requireCoverageMetadata', $root->getAttribute('forceCoversAnnotation'));
  88615. $root->removeAttribute('forceCoversAnnotation');
  88616. }
  88617. }
  88618. <?php
  88619. declare (strict_types=1);
  88620. /*
  88621. * This file is part of PHPUnit.
  88622. *
  88623. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88624. *
  88625. * For the full copyright and license information, please view the LICENSE
  88626. * file that was distributed with this source code.
  88627. */
  88628. namespace PHPUnit\TextUI\XmlConfiguration;
  88629. use function assert;
  88630. use DOMDocument;
  88631. use DOMElement;
  88632. use PHPUnit\Runner\Version;
  88633. /**
  88634. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88635. *
  88636. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88637. */
  88638. final class UpdateSchemaLocation implements \PHPUnit\TextUI\XmlConfiguration\Migration
  88639. {
  88640. public function migrate(DOMDocument $document): void
  88641. {
  88642. $root = $document->documentElement;
  88643. assert($root instanceof DOMElement);
  88644. $root->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation', 'https://schema.phpunit.de/' . Version::series() . '/phpunit.xsd');
  88645. }
  88646. }
  88647. <?php
  88648. declare (strict_types=1);
  88649. /*
  88650. * This file is part of PHPUnit.
  88651. *
  88652. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88653. *
  88654. * For the full copyright and license information, please view the LICENSE
  88655. * file that was distributed with this source code.
  88656. */
  88657. namespace PHPUnit\TextUI\XmlConfiguration;
  88658. use PHPUnit\Runner\Version;
  88659. use PHPUnit\Util\Xml\Loader as XmlLoader;
  88660. use PHPUnit\Util\Xml\XmlException;
  88661. /**
  88662. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88663. *
  88664. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88665. */
  88666. final class Migrator
  88667. {
  88668. /**
  88669. * @throws Exception
  88670. * @throws MigrationException
  88671. * @throws XmlException
  88672. */
  88673. public function migrate(string $filename): string
  88674. {
  88675. $origin = (new \PHPUnit\TextUI\XmlConfiguration\SchemaDetector())->detect($filename);
  88676. if (!$origin->detected()) {
  88677. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not validate against any known schema');
  88678. }
  88679. if ($origin->version() === Version::series()) {
  88680. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not need to be migrated');
  88681. }
  88682. $configurationDocument = (new XmlLoader())->loadFile($filename);
  88683. foreach ((new \PHPUnit\TextUI\XmlConfiguration\MigrationBuilder())->build($origin->version()) as $migration) {
  88684. $migration->migrate($configurationDocument);
  88685. }
  88686. $configurationDocument->formatOutput = \true;
  88687. $configurationDocument->preserveWhiteSpace = \false;
  88688. return $configurationDocument->saveXML();
  88689. }
  88690. }
  88691. <?php
  88692. declare (strict_types=1);
  88693. /*
  88694. * This file is part of PHPUnit.
  88695. *
  88696. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88697. *
  88698. * For the full copyright and license information, please view the LICENSE
  88699. * file that was distributed with this source code.
  88700. */
  88701. namespace PHPUnit\TextUI\XmlConfiguration;
  88702. use function count;
  88703. use ArrayIterator;
  88704. use Countable;
  88705. use DOMNode;
  88706. use DOMNodeList;
  88707. use IteratorAggregate;
  88708. /**
  88709. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88710. *
  88711. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88712. *
  88713. * @template-implements IteratorAggregate<int, DOMNode>
  88714. */
  88715. final class SnapshotNodeList implements Countable, IteratorAggregate
  88716. {
  88717. /**
  88718. * @psalm-var list<DOMNode>
  88719. */
  88720. private array $nodes = [];
  88721. public static function fromNodeList(DOMNodeList $list): self
  88722. {
  88723. $snapshot = new self();
  88724. foreach ($list as $node) {
  88725. $snapshot->nodes[] = $node;
  88726. }
  88727. return $snapshot;
  88728. }
  88729. public function count(): int
  88730. {
  88731. return count($this->nodes);
  88732. }
  88733. public function getIterator(): ArrayIterator
  88734. {
  88735. return new ArrayIterator($this->nodes);
  88736. }
  88737. }
  88738. <?php
  88739. declare (strict_types=1);
  88740. /*
  88741. * This file is part of PHPUnit.
  88742. *
  88743. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  88744. *
  88745. * For the full copyright and license information, please view the LICENSE
  88746. * file that was distributed with this source code.
  88747. */
  88748. namespace PHPUnit\TextUI\XmlConfiguration;
  88749. /**
  88750. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  88751. *
  88752. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  88753. *
  88754. * @psalm-immutable
  88755. */
  88756. final class PHPUnit
  88757. {
  88758. private readonly ?string $cacheDirectory;
  88759. private readonly bool $cacheResult;
  88760. private readonly ?string $cacheResultFile;
  88761. private readonly int|string $columns;
  88762. private readonly string $colors;
  88763. private readonly bool $stderr;
  88764. private readonly bool $displayDetailsOnIncompleteTests;
  88765. private readonly bool $displayDetailsOnSkippedTests;
  88766. private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
  88767. private readonly bool $displayDetailsOnPhpunitDeprecations;
  88768. private readonly bool $displayDetailsOnTestsThatTriggerErrors;
  88769. private readonly bool $displayDetailsOnTestsThatTriggerNotices;
  88770. private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
  88771. private readonly bool $reverseDefectList;
  88772. private readonly bool $requireCoverageMetadata;
  88773. private readonly ?string $bootstrap;
  88774. private readonly bool $processIsolation;
  88775. private readonly bool $failOnDeprecation;
  88776. private readonly bool $failOnPhpunitDeprecation;
  88777. private readonly bool $failOnEmptyTestSuite;
  88778. private readonly bool $failOnIncomplete;
  88779. private readonly bool $failOnNotice;
  88780. private readonly bool $failOnRisky;
  88781. private readonly bool $failOnSkipped;
  88782. private readonly bool $failOnWarning;
  88783. private readonly bool $stopOnDefect;
  88784. private readonly bool $stopOnDeprecation;
  88785. private readonly bool $stopOnError;
  88786. private readonly bool $stopOnFailure;
  88787. private readonly bool $stopOnIncomplete;
  88788. private readonly bool $stopOnNotice;
  88789. private readonly bool $stopOnRisky;
  88790. private readonly bool $stopOnSkipped;
  88791. private readonly bool $stopOnWarning;
  88792. /**
  88793. * @psalm-var ?non-empty-string
  88794. */
  88795. private readonly ?string $extensionsDirectory;
  88796. private readonly bool $beStrictAboutChangesToGlobalState;
  88797. private readonly bool $beStrictAboutOutputDuringTests;
  88798. private readonly bool $beStrictAboutTestsThatDoNotTestAnything;
  88799. private readonly bool $beStrictAboutCoverageMetadata;
  88800. private readonly bool $enforceTimeLimit;
  88801. private readonly int $defaultTimeLimit;
  88802. private readonly int $timeoutForSmallTests;
  88803. private readonly int $timeoutForMediumTests;
  88804. private readonly int $timeoutForLargeTests;
  88805. private readonly ?string $defaultTestSuite;
  88806. private readonly int $executionOrder;
  88807. private readonly bool $resolveDependencies;
  88808. private readonly bool $defectsFirst;
  88809. private readonly bool $backupGlobals;
  88810. private readonly bool $backupStaticProperties;
  88811. private readonly bool $registerMockObjectsFromTestArgumentsRecursively;
  88812. private readonly bool $testdoxPrinter;
  88813. private readonly bool $controlGarbageCollector;
  88814. private readonly int $numberOfTestsBeforeGarbageCollection;
  88815. /**
  88816. * @psalm-param ?non-empty-string $extensionsDirectory
  88817. */
  88818. public function __construct(?string $cacheDirectory, bool $cacheResult, ?string $cacheResultFile, int|string $columns, string $colors, bool $stderr, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, ?string $bootstrap, bool $processIsolation, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, ?string $extensionsDirectory, bool $beStrictAboutChangesToGlobalState, bool $beStrictAboutOutputDuringTests, bool $beStrictAboutTestsThatDoNotTestAnything, bool $beStrictAboutCoverageMetadata, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, ?string $defaultTestSuite, int $executionOrder, bool $resolveDependencies, bool $defectsFirst, bool $backupGlobals, bool $backupStaticProperties, bool $registerMockObjectsFromTestArgumentsRecursively, bool $testdoxPrinter, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection)
  88819. {
  88820. $this->cacheDirectory = $cacheDirectory;
  88821. $this->cacheResult = $cacheResult;
  88822. $this->cacheResultFile = $cacheResultFile;
  88823. $this->columns = $columns;
  88824. $this->colors = $colors;
  88825. $this->stderr = $stderr;
  88826. $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
  88827. $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
  88828. $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
  88829. $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
  88830. $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
  88831. $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
  88832. $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
  88833. $this->reverseDefectList = $reverseDefectList;
  88834. $this->requireCoverageMetadata = $requireCoverageMetadata;
  88835. $this->bootstrap = $bootstrap;
  88836. $this->processIsolation = $processIsolation;
  88837. $this->failOnDeprecation = $failOnDeprecation;
  88838. $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
  88839. $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
  88840. $this->failOnIncomplete = $failOnIncomplete;
  88841. $this->failOnNotice = $failOnNotice;
  88842. $this->failOnRisky = $failOnRisky;
  88843. $this->failOnSkipped = $failOnSkipped;
  88844. $this->failOnWarning = $failOnWarning;
  88845. $this->stopOnDefect = $stopOnDefect;
  88846. $this->stopOnDeprecation = $stopOnDeprecation;
  88847. $this->stopOnError = $stopOnError;
  88848. $this->stopOnFailure = $stopOnFailure;
  88849. $this->stopOnIncomplete = $stopOnIncomplete;
  88850. $this->stopOnNotice = $stopOnNotice;
  88851. $this->stopOnRisky = $stopOnRisky;
  88852. $this->stopOnSkipped = $stopOnSkipped;
  88853. $this->stopOnWarning = $stopOnWarning;
  88854. $this->extensionsDirectory = $extensionsDirectory;
  88855. $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
  88856. $this->beStrictAboutOutputDuringTests = $beStrictAboutOutputDuringTests;
  88857. $this->beStrictAboutTestsThatDoNotTestAnything = $beStrictAboutTestsThatDoNotTestAnything;
  88858. $this->beStrictAboutCoverageMetadata = $beStrictAboutCoverageMetadata;
  88859. $this->enforceTimeLimit = $enforceTimeLimit;
  88860. $this->defaultTimeLimit = $defaultTimeLimit;
  88861. $this->timeoutForSmallTests = $timeoutForSmallTests;
  88862. $this->timeoutForMediumTests = $timeoutForMediumTests;
  88863. $this->timeoutForLargeTests = $timeoutForLargeTests;
  88864. $this->defaultTestSuite = $defaultTestSuite;
  88865. $this->executionOrder = $executionOrder;
  88866. $this->resolveDependencies = $resolveDependencies;
  88867. $this->defectsFirst = $defectsFirst;
  88868. $this->backupGlobals = $backupGlobals;
  88869. $this->backupStaticProperties = $backupStaticProperties;
  88870. $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively;
  88871. $this->testdoxPrinter = $testdoxPrinter;
  88872. $this->controlGarbageCollector = $controlGarbageCollector;
  88873. $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection;
  88874. }
  88875. /**
  88876. * @psalm-assert-if-true !null $this->cacheDirectory
  88877. */
  88878. public function hasCacheDirectory(): bool
  88879. {
  88880. return $this->cacheDirectory !== null;
  88881. }
  88882. /**
  88883. * @throws Exception
  88884. */
  88885. public function cacheDirectory(): string
  88886. {
  88887. if (!$this->hasCacheDirectory()) {
  88888. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Cache directory is not configured');
  88889. }
  88890. return $this->cacheDirectory;
  88891. }
  88892. public function cacheResult(): bool
  88893. {
  88894. return $this->cacheResult;
  88895. }
  88896. /**
  88897. * @psalm-assert-if-true !null $this->cacheResultFile
  88898. *
  88899. * @deprecated
  88900. */
  88901. public function hasCacheResultFile(): bool
  88902. {
  88903. return $this->cacheResultFile !== null;
  88904. }
  88905. /**
  88906. * @throws Exception
  88907. *
  88908. * @deprecated
  88909. */
  88910. public function cacheResultFile(): string
  88911. {
  88912. if (!$this->hasCacheResultFile()) {
  88913. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Cache result file is not configured');
  88914. }
  88915. return $this->cacheResultFile;
  88916. }
  88917. public function columns(): int|string
  88918. {
  88919. return $this->columns;
  88920. }
  88921. public function colors(): string
  88922. {
  88923. return $this->colors;
  88924. }
  88925. public function stderr(): bool
  88926. {
  88927. return $this->stderr;
  88928. }
  88929. public function displayDetailsOnIncompleteTests(): bool
  88930. {
  88931. return $this->displayDetailsOnIncompleteTests;
  88932. }
  88933. public function displayDetailsOnSkippedTests(): bool
  88934. {
  88935. return $this->displayDetailsOnSkippedTests;
  88936. }
  88937. public function displayDetailsOnTestsThatTriggerDeprecations(): bool
  88938. {
  88939. return $this->displayDetailsOnTestsThatTriggerDeprecations;
  88940. }
  88941. public function displayDetailsOnPhpunitDeprecations(): bool
  88942. {
  88943. return $this->displayDetailsOnPhpunitDeprecations;
  88944. }
  88945. public function displayDetailsOnTestsThatTriggerErrors(): bool
  88946. {
  88947. return $this->displayDetailsOnTestsThatTriggerErrors;
  88948. }
  88949. public function displayDetailsOnTestsThatTriggerNotices(): bool
  88950. {
  88951. return $this->displayDetailsOnTestsThatTriggerNotices;
  88952. }
  88953. public function displayDetailsOnTestsThatTriggerWarnings(): bool
  88954. {
  88955. return $this->displayDetailsOnTestsThatTriggerWarnings;
  88956. }
  88957. public function reverseDefectList(): bool
  88958. {
  88959. return $this->reverseDefectList;
  88960. }
  88961. public function requireCoverageMetadata(): bool
  88962. {
  88963. return $this->requireCoverageMetadata;
  88964. }
  88965. /**
  88966. * @psalm-assert-if-true !null $this->bootstrap
  88967. */
  88968. public function hasBootstrap(): bool
  88969. {
  88970. return $this->bootstrap !== null;
  88971. }
  88972. /**
  88973. * @throws Exception
  88974. */
  88975. public function bootstrap(): string
  88976. {
  88977. if (!$this->hasBootstrap()) {
  88978. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Bootstrap script is not configured');
  88979. }
  88980. return $this->bootstrap;
  88981. }
  88982. public function processIsolation(): bool
  88983. {
  88984. return $this->processIsolation;
  88985. }
  88986. public function failOnDeprecation(): bool
  88987. {
  88988. return $this->failOnDeprecation;
  88989. }
  88990. public function failOnPhpunitDeprecation(): bool
  88991. {
  88992. return $this->failOnPhpunitDeprecation;
  88993. }
  88994. public function failOnEmptyTestSuite(): bool
  88995. {
  88996. return $this->failOnEmptyTestSuite;
  88997. }
  88998. public function failOnIncomplete(): bool
  88999. {
  89000. return $this->failOnIncomplete;
  89001. }
  89002. public function failOnNotice(): bool
  89003. {
  89004. return $this->failOnNotice;
  89005. }
  89006. public function failOnRisky(): bool
  89007. {
  89008. return $this->failOnRisky;
  89009. }
  89010. public function failOnSkipped(): bool
  89011. {
  89012. return $this->failOnSkipped;
  89013. }
  89014. public function failOnWarning(): bool
  89015. {
  89016. return $this->failOnWarning;
  89017. }
  89018. public function stopOnDefect(): bool
  89019. {
  89020. return $this->stopOnDefect;
  89021. }
  89022. public function stopOnDeprecation(): bool
  89023. {
  89024. return $this->stopOnDeprecation;
  89025. }
  89026. public function stopOnError(): bool
  89027. {
  89028. return $this->stopOnError;
  89029. }
  89030. public function stopOnFailure(): bool
  89031. {
  89032. return $this->stopOnFailure;
  89033. }
  89034. public function stopOnIncomplete(): bool
  89035. {
  89036. return $this->stopOnIncomplete;
  89037. }
  89038. public function stopOnNotice(): bool
  89039. {
  89040. return $this->stopOnNotice;
  89041. }
  89042. public function stopOnRisky(): bool
  89043. {
  89044. return $this->stopOnRisky;
  89045. }
  89046. public function stopOnSkipped(): bool
  89047. {
  89048. return $this->stopOnSkipped;
  89049. }
  89050. public function stopOnWarning(): bool
  89051. {
  89052. return $this->stopOnWarning;
  89053. }
  89054. /**
  89055. * @psalm-assert-if-true !null $this->extensionsDirectory
  89056. */
  89057. public function hasExtensionsDirectory(): bool
  89058. {
  89059. return $this->extensionsDirectory !== null;
  89060. }
  89061. /**
  89062. * @psalm-return non-empty-string
  89063. *
  89064. * @throws Exception
  89065. */
  89066. public function extensionsDirectory(): string
  89067. {
  89068. if (!$this->hasExtensionsDirectory()) {
  89069. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Extensions directory is not configured');
  89070. }
  89071. return $this->extensionsDirectory;
  89072. }
  89073. public function beStrictAboutChangesToGlobalState(): bool
  89074. {
  89075. return $this->beStrictAboutChangesToGlobalState;
  89076. }
  89077. public function beStrictAboutOutputDuringTests(): bool
  89078. {
  89079. return $this->beStrictAboutOutputDuringTests;
  89080. }
  89081. public function beStrictAboutTestsThatDoNotTestAnything(): bool
  89082. {
  89083. return $this->beStrictAboutTestsThatDoNotTestAnything;
  89084. }
  89085. public function beStrictAboutCoverageMetadata(): bool
  89086. {
  89087. return $this->beStrictAboutCoverageMetadata;
  89088. }
  89089. public function enforceTimeLimit(): bool
  89090. {
  89091. return $this->enforceTimeLimit;
  89092. }
  89093. public function defaultTimeLimit(): int
  89094. {
  89095. return $this->defaultTimeLimit;
  89096. }
  89097. public function timeoutForSmallTests(): int
  89098. {
  89099. return $this->timeoutForSmallTests;
  89100. }
  89101. public function timeoutForMediumTests(): int
  89102. {
  89103. return $this->timeoutForMediumTests;
  89104. }
  89105. public function timeoutForLargeTests(): int
  89106. {
  89107. return $this->timeoutForLargeTests;
  89108. }
  89109. /**
  89110. * @psalm-assert-if-true !null $this->defaultTestSuite
  89111. */
  89112. public function hasDefaultTestSuite(): bool
  89113. {
  89114. return $this->defaultTestSuite !== null;
  89115. }
  89116. /**
  89117. * @throws Exception
  89118. */
  89119. public function defaultTestSuite(): string
  89120. {
  89121. if (!$this->hasDefaultTestSuite()) {
  89122. throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Default test suite is not configured');
  89123. }
  89124. return $this->defaultTestSuite;
  89125. }
  89126. public function executionOrder(): int
  89127. {
  89128. return $this->executionOrder;
  89129. }
  89130. public function resolveDependencies(): bool
  89131. {
  89132. return $this->resolveDependencies;
  89133. }
  89134. public function defectsFirst(): bool
  89135. {
  89136. return $this->defectsFirst;
  89137. }
  89138. public function backupGlobals(): bool
  89139. {
  89140. return $this->backupGlobals;
  89141. }
  89142. public function backupStaticProperties(): bool
  89143. {
  89144. return $this->backupStaticProperties;
  89145. }
  89146. /**
  89147. * @deprecated
  89148. */
  89149. public function registerMockObjectsFromTestArgumentsRecursively(): bool
  89150. {
  89151. return $this->registerMockObjectsFromTestArgumentsRecursively;
  89152. }
  89153. public function testdoxPrinter(): bool
  89154. {
  89155. return $this->testdoxPrinter;
  89156. }
  89157. public function controlGarbageCollector(): bool
  89158. {
  89159. return $this->controlGarbageCollector;
  89160. }
  89161. public function numberOfTestsBeforeGarbageCollection(): int
  89162. {
  89163. return $this->numberOfTestsBeforeGarbageCollection;
  89164. }
  89165. }
  89166. <?php
  89167. declare (strict_types=1);
  89168. /*
  89169. * This file is part of PHPUnit.
  89170. *
  89171. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89172. *
  89173. * For the full copyright and license information, please view the LICENSE
  89174. * file that was distributed with this source code.
  89175. */
  89176. namespace PHPUnit\TextUI\XmlConfiguration;
  89177. /**
  89178. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89179. *
  89180. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89181. *
  89182. * @psalm-immutable
  89183. */
  89184. final class FailedSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
  89185. {
  89186. }
  89187. <?php
  89188. declare (strict_types=1);
  89189. /*
  89190. * This file is part of PHPUnit.
  89191. *
  89192. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89193. *
  89194. * For the full copyright and license information, please view the LICENSE
  89195. * file that was distributed with this source code.
  89196. */
  89197. namespace PHPUnit\TextUI\XmlConfiguration;
  89198. use PHPUnit\Util\Xml\XmlException;
  89199. /**
  89200. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89201. *
  89202. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89203. *
  89204. * @psalm-immutable
  89205. */
  89206. abstract class SchemaDetectionResult
  89207. {
  89208. /**
  89209. * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this
  89210. */
  89211. public function detected(): bool
  89212. {
  89213. return \false;
  89214. }
  89215. /**
  89216. * @throws XmlException
  89217. */
  89218. public function version(): string
  89219. {
  89220. throw new XmlException('No supported schema was detected');
  89221. }
  89222. }
  89223. <?php
  89224. declare (strict_types=1);
  89225. /*
  89226. * This file is part of PHPUnit.
  89227. *
  89228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89229. *
  89230. * For the full copyright and license information, please view the LICENSE
  89231. * file that was distributed with this source code.
  89232. */
  89233. namespace PHPUnit\TextUI\XmlConfiguration;
  89234. use PHPUnit\Util\Xml\Loader;
  89235. use PHPUnit\Util\Xml\XmlException;
  89236. /**
  89237. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89238. *
  89239. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89240. */
  89241. final class SchemaDetector
  89242. {
  89243. /**
  89244. * @throws XmlException
  89245. */
  89246. public function detect(string $filename): \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
  89247. {
  89248. $document = (new Loader())->loadFile($filename);
  89249. $schemaFinder = new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder();
  89250. foreach ($schemaFinder->available() as $candidate) {
  89251. $schema = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find($candidate);
  89252. if (!(new \PHPUnit\TextUI\XmlConfiguration\Validator())->validate($document, $schema)->hasValidationErrors()) {
  89253. return new \PHPUnit\TextUI\XmlConfiguration\SuccessfulSchemaDetectionResult($candidate);
  89254. }
  89255. }
  89256. return new \PHPUnit\TextUI\XmlConfiguration\FailedSchemaDetectionResult();
  89257. }
  89258. }
  89259. <?php
  89260. declare (strict_types=1);
  89261. /*
  89262. * This file is part of PHPUnit.
  89263. *
  89264. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89265. *
  89266. * For the full copyright and license information, please view the LICENSE
  89267. * file that was distributed with this source code.
  89268. */
  89269. namespace PHPUnit\TextUI\XmlConfiguration;
  89270. /**
  89271. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89272. *
  89273. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89274. *
  89275. * @psalm-immutable
  89276. */
  89277. final class SuccessfulSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
  89278. {
  89279. /**
  89280. * @psalm-var non-empty-string
  89281. */
  89282. private readonly string $version;
  89283. /**
  89284. * @psalm-param non-empty-string $version
  89285. */
  89286. public function __construct(string $version)
  89287. {
  89288. $this->version = $version;
  89289. }
  89290. /**
  89291. * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this
  89292. */
  89293. public function detected(): bool
  89294. {
  89295. return \true;
  89296. }
  89297. /**
  89298. * @psalm-return non-empty-string
  89299. */
  89300. public function version(): string
  89301. {
  89302. return $this->version;
  89303. }
  89304. }
  89305. <?php
  89306. declare (strict_types=1);
  89307. /*
  89308. * This file is part of PHPUnit.
  89309. *
  89310. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89311. *
  89312. * For the full copyright and license information, please view the LICENSE
  89313. * file that was distributed with this source code.
  89314. */
  89315. namespace PHPUnit\TextUI\XmlConfiguration;
  89316. use function assert;
  89317. use function defined;
  89318. use function is_file;
  89319. use function rsort;
  89320. use function sprintf;
  89321. use DirectoryIterator;
  89322. use PHPUnit\Runner\Version;
  89323. /**
  89324. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89325. *
  89326. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89327. */
  89328. final class SchemaFinder
  89329. {
  89330. /**
  89331. * @psalm-return non-empty-list<non-empty-string>
  89332. */
  89333. public function available(): array
  89334. {
  89335. $result = [Version::series()];
  89336. foreach (new DirectoryIterator($this->path() . 'schema') as $file) {
  89337. if ($file->isDot()) {
  89338. continue;
  89339. }
  89340. $version = $file->getBasename('.xsd');
  89341. assert(!empty($version));
  89342. $result[] = $version;
  89343. }
  89344. rsort($result);
  89345. return $result;
  89346. }
  89347. /**
  89348. * @throws CannotFindSchemaException
  89349. */
  89350. public function find(string $version): string
  89351. {
  89352. if ($version === Version::series()) {
  89353. $filename = $this->path() . 'phpunit.xsd';
  89354. } else {
  89355. $filename = $this->path() . 'schema/' . $version . '.xsd';
  89356. }
  89357. if (!is_file($filename)) {
  89358. throw new \PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException(sprintf('Schema for PHPUnit %s is not available', $version));
  89359. }
  89360. return $filename;
  89361. }
  89362. private function path(): string
  89363. {
  89364. if (defined('__PHPUNIT_PHAR_ROOT__')) {
  89365. return __PHPUNIT_PHAR_ROOT__ . '/';
  89366. }
  89367. return __DIR__ . '/../../../../';
  89368. }
  89369. }
  89370. <?php
  89371. declare (strict_types=1);
  89372. /*
  89373. * This file is part of PHPUnit.
  89374. *
  89375. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89376. *
  89377. * For the full copyright and license information, please view the LICENSE
  89378. * file that was distributed with this source code.
  89379. */
  89380. namespace PHPUnit\TextUI\XmlConfiguration;
  89381. use const PHP_VERSION;
  89382. use function array_merge;
  89383. use function array_unique;
  89384. use function explode;
  89385. use function in_array;
  89386. use function is_dir;
  89387. use function is_file;
  89388. use function str_contains;
  89389. use function version_compare;
  89390. use PHPUnit\Framework\Exception as FrameworkException;
  89391. use PHPUnit\Framework\TestSuite as TestSuiteObject;
  89392. use PHPUnit\TextUI\Configuration\TestSuiteCollection;
  89393. use PHPUnit\TextUI\RuntimeException;
  89394. use PHPUnit\TextUI\TestDirectoryNotFoundException;
  89395. use PHPUnit\TextUI\TestFileNotFoundException;
  89396. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade;
  89397. /**
  89398. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89399. *
  89400. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89401. */
  89402. final class TestSuiteMapper
  89403. {
  89404. /**
  89405. * @psalm-param non-empty-string $xmlConfigurationFile,
  89406. *
  89407. * @throws RuntimeException
  89408. * @throws TestDirectoryNotFoundException
  89409. * @throws TestFileNotFoundException
  89410. */
  89411. public function map(string $xmlConfigurationFile, TestSuiteCollection $configuration, string $filter, string $excludedTestSuites): TestSuiteObject
  89412. {
  89413. try {
  89414. $filterAsArray = $filter ? explode(',', $filter) : [];
  89415. $excludedFilterAsArray = $excludedTestSuites ? explode(',', $excludedTestSuites) : [];
  89416. $result = TestSuiteObject::empty($xmlConfigurationFile);
  89417. foreach ($configuration as $testSuiteConfiguration) {
  89418. if (!empty($filterAsArray) && !in_array($testSuiteConfiguration->name(), $filterAsArray, \true)) {
  89419. continue;
  89420. }
  89421. if (!empty($excludedFilterAsArray) && in_array($testSuiteConfiguration->name(), $excludedFilterAsArray, \true)) {
  89422. continue;
  89423. }
  89424. $exclude = [];
  89425. foreach ($testSuiteConfiguration->exclude()->asArray() as $file) {
  89426. $exclude[] = $file->path();
  89427. }
  89428. $files = [];
  89429. foreach ($testSuiteConfiguration->directories() as $directory) {
  89430. if (!str_contains($directory->path(), '*') && !is_dir($directory->path())) {
  89431. throw new TestDirectoryNotFoundException($directory->path());
  89432. }
  89433. if (!version_compare(PHP_VERSION, $directory->phpVersion(), $directory->phpVersionOperator()->asString())) {
  89434. continue;
  89435. }
  89436. $files = array_merge($files, (new Facade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix(), $exclude));
  89437. }
  89438. foreach ($testSuiteConfiguration->files() as $file) {
  89439. if (!is_file($file->path())) {
  89440. throw new TestFileNotFoundException($file->path());
  89441. }
  89442. if (!version_compare(PHP_VERSION, $file->phpVersion(), $file->phpVersionOperator()->asString())) {
  89443. continue;
  89444. }
  89445. $files[] = $file->path();
  89446. }
  89447. if (!empty($files)) {
  89448. $testSuite = TestSuiteObject::empty($testSuiteConfiguration->name());
  89449. $testSuite->addTestFiles(array_unique($files));
  89450. $result->addTest($testSuite);
  89451. }
  89452. }
  89453. return $result;
  89454. } catch (FrameworkException $e) {
  89455. throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
  89456. }
  89457. }
  89458. }
  89459. <?php
  89460. declare (strict_types=1);
  89461. /*
  89462. * This file is part of PHPUnit.
  89463. *
  89464. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89465. *
  89466. * For the full copyright and license information, please view the LICENSE
  89467. * file that was distributed with this source code.
  89468. */
  89469. namespace PHPUnit\TextUI\XmlConfiguration;
  89470. use const PHP_EOL;
  89471. use function sprintf;
  89472. use function trim;
  89473. use LibXMLError;
  89474. /**
  89475. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89476. *
  89477. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89478. *
  89479. * @psalm-immutable
  89480. */
  89481. final class ValidationResult
  89482. {
  89483. /**
  89484. * @psalm-var array<int,list<string>>
  89485. */
  89486. private readonly array $validationErrors;
  89487. /**
  89488. * @psalm-param array<int,LibXMLError> $errors
  89489. */
  89490. public static function fromArray(array $errors): self
  89491. {
  89492. $validationErrors = [];
  89493. foreach ($errors as $error) {
  89494. if (!isset($validationErrors[$error->line])) {
  89495. $validationErrors[$error->line] = [];
  89496. }
  89497. $validationErrors[$error->line][] = trim($error->message);
  89498. }
  89499. return new self($validationErrors);
  89500. }
  89501. private function __construct(array $validationErrors)
  89502. {
  89503. $this->validationErrors = $validationErrors;
  89504. }
  89505. public function hasValidationErrors(): bool
  89506. {
  89507. return !empty($this->validationErrors);
  89508. }
  89509. public function asString(): string
  89510. {
  89511. $buffer = '';
  89512. foreach ($this->validationErrors as $line => $validationErrorsOnLine) {
  89513. $buffer .= sprintf(PHP_EOL . ' Line %d:' . PHP_EOL, $line);
  89514. foreach ($validationErrorsOnLine as $validationError) {
  89515. $buffer .= sprintf(' - %s' . PHP_EOL, $validationError);
  89516. }
  89517. }
  89518. return $buffer;
  89519. }
  89520. }
  89521. <?php
  89522. declare (strict_types=1);
  89523. /*
  89524. * This file is part of PHPUnit.
  89525. *
  89526. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89527. *
  89528. * For the full copyright and license information, please view the LICENSE
  89529. * file that was distributed with this source code.
  89530. */
  89531. namespace PHPUnit\TextUI\XmlConfiguration;
  89532. use function file_get_contents;
  89533. use function libxml_clear_errors;
  89534. use function libxml_get_errors;
  89535. use function libxml_use_internal_errors;
  89536. use DOMDocument;
  89537. /**
  89538. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89539. *
  89540. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89541. */
  89542. final class Validator
  89543. {
  89544. public function validate(DOMDocument $document, string $xsdFilename): \PHPUnit\TextUI\XmlConfiguration\ValidationResult
  89545. {
  89546. $originalErrorHandling = libxml_use_internal_errors(\true);
  89547. $document->schemaValidateSource(file_get_contents($xsdFilename));
  89548. $errors = libxml_get_errors();
  89549. libxml_clear_errors();
  89550. libxml_use_internal_errors($originalErrorHandling);
  89551. return \PHPUnit\TextUI\XmlConfiguration\ValidationResult::fromArray($errors);
  89552. }
  89553. }
  89554. <?php
  89555. declare (strict_types=1);
  89556. /*
  89557. * This file is part of PHPUnit.
  89558. *
  89559. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89560. *
  89561. * For the full copyright and license information, please view the LICENSE
  89562. * file that was distributed with this source code.
  89563. */
  89564. namespace PHPUnit\TextUI;
  89565. use function sprintf;
  89566. use RuntimeException;
  89567. /**
  89568. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89569. *
  89570. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89571. */
  89572. final class CannotOpenSocketException extends RuntimeException implements \PHPUnit\TextUI\Exception
  89573. {
  89574. public function __construct(string $hostname, int $port)
  89575. {
  89576. parent::__construct(sprintf('Cannot open socket %s:%d', $hostname, $port));
  89577. }
  89578. }
  89579. <?php
  89580. declare (strict_types=1);
  89581. /*
  89582. * This file is part of PHPUnit.
  89583. *
  89584. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89585. *
  89586. * For the full copyright and license information, please view the LICENSE
  89587. * file that was distributed with this source code.
  89588. */
  89589. namespace PHPUnit\TextUI;
  89590. use Throwable;
  89591. /**
  89592. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89593. *
  89594. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  89595. */
  89596. interface Exception extends Throwable
  89597. {
  89598. }
  89599. <?php
  89600. declare (strict_types=1);
  89601. /*
  89602. * This file is part of PHPUnit.
  89603. *
  89604. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89605. *
  89606. * For the full copyright and license information, please view the LICENSE
  89607. * file that was distributed with this source code.
  89608. */
  89609. namespace PHPUnit\TextUI;
  89610. use function sprintf;
  89611. use RuntimeException;
  89612. /**
  89613. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89614. *
  89615. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89616. */
  89617. final class InvalidSocketException extends RuntimeException implements \PHPUnit\TextUI\Exception
  89618. {
  89619. public function __construct(string $socket)
  89620. {
  89621. parent::__construct(sprintf('"%s" does not match "socket://hostname:port" format', $socket));
  89622. }
  89623. }
  89624. <?php
  89625. declare (strict_types=1);
  89626. /*
  89627. * This file is part of PHPUnit.
  89628. *
  89629. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89630. *
  89631. * For the full copyright and license information, please view the LICENSE
  89632. * file that was distributed with this source code.
  89633. */
  89634. namespace PHPUnit\TextUI;
  89635. /**
  89636. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89637. *
  89638. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89639. */
  89640. final class RuntimeException extends \RuntimeException implements \PHPUnit\TextUI\Exception
  89641. {
  89642. }
  89643. <?php
  89644. declare (strict_types=1);
  89645. /*
  89646. * This file is part of PHPUnit.
  89647. *
  89648. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89649. *
  89650. * For the full copyright and license information, please view the LICENSE
  89651. * file that was distributed with this source code.
  89652. */
  89653. namespace PHPUnit\TextUI;
  89654. use function sprintf;
  89655. use RuntimeException;
  89656. /**
  89657. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89658. *
  89659. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89660. */
  89661. final class TestDirectoryNotFoundException extends RuntimeException implements \PHPUnit\TextUI\Exception
  89662. {
  89663. public function __construct(string $path)
  89664. {
  89665. parent::__construct(sprintf('Test directory "%s" not found', $path));
  89666. }
  89667. }
  89668. <?php
  89669. declare (strict_types=1);
  89670. /*
  89671. * This file is part of PHPUnit.
  89672. *
  89673. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89674. *
  89675. * For the full copyright and license information, please view the LICENSE
  89676. * file that was distributed with this source code.
  89677. */
  89678. namespace PHPUnit\TextUI;
  89679. use function sprintf;
  89680. use RuntimeException;
  89681. /**
  89682. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89683. *
  89684. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89685. */
  89686. final class TestFileNotFoundException extends RuntimeException implements \PHPUnit\TextUI\Exception
  89687. {
  89688. public function __construct(string $path)
  89689. {
  89690. parent::__construct(sprintf('Test file "%s" not found', $path));
  89691. }
  89692. }
  89693. <?php
  89694. declare (strict_types=1);
  89695. /*
  89696. * This file is part of PHPUnit.
  89697. *
  89698. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89699. *
  89700. * For the full copyright and license information, please view the LICENSE
  89701. * file that was distributed with this source code.
  89702. */
  89703. namespace PHPUnit\TextUI;
  89704. use const PHP_EOL;
  89705. use function count;
  89706. use function defined;
  89707. use function explode;
  89708. use function max;
  89709. use function preg_replace_callback;
  89710. use function str_pad;
  89711. use function str_repeat;
  89712. use function strlen;
  89713. use function wordwrap;
  89714. use PHPUnit\Util\Color;
  89715. use PHPUnitPHAR\SebastianBergmann\Environment\Console;
  89716. /**
  89717. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89718. *
  89719. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89720. */
  89721. final class Help
  89722. {
  89723. private const LEFT_MARGIN = ' ';
  89724. private int $lengthOfLongestOptionName = 0;
  89725. private readonly int $columnsAvailableForDescription;
  89726. private ?bool $hasColor;
  89727. public function __construct(?int $width = null, ?bool $withColor = null)
  89728. {
  89729. if ($width === null) {
  89730. $width = (new Console())->getNumberOfColumns();
  89731. }
  89732. if ($withColor === null) {
  89733. $this->hasColor = (new Console())->hasColorSupport();
  89734. } else {
  89735. $this->hasColor = $withColor;
  89736. }
  89737. foreach ($this->elements() as $options) {
  89738. foreach ($options as $option) {
  89739. if (isset($option['arg'])) {
  89740. $this->lengthOfLongestOptionName = max($this->lengthOfLongestOptionName, strlen($option['arg']));
  89741. }
  89742. }
  89743. }
  89744. $this->columnsAvailableForDescription = $width - $this->lengthOfLongestOptionName - 4;
  89745. }
  89746. public function generate(): string
  89747. {
  89748. if ($this->hasColor) {
  89749. return $this->writeWithColor();
  89750. }
  89751. return $this->writeWithoutColor();
  89752. }
  89753. private function writeWithoutColor(): string
  89754. {
  89755. $buffer = '';
  89756. foreach ($this->elements() as $section => $options) {
  89757. $buffer .= "{$section}:" . PHP_EOL;
  89758. if ($section !== 'Usage') {
  89759. $buffer .= PHP_EOL;
  89760. }
  89761. foreach ($options as $option) {
  89762. if (isset($option['spacer'])) {
  89763. $buffer .= PHP_EOL;
  89764. }
  89765. if (isset($option['text'])) {
  89766. $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL;
  89767. }
  89768. if (isset($option['arg'])) {
  89769. $arg = str_pad($option['arg'], $this->lengthOfLongestOptionName);
  89770. $buffer .= self::LEFT_MARGIN . $arg . ' ' . $option['desc'] . PHP_EOL;
  89771. }
  89772. }
  89773. $buffer .= PHP_EOL;
  89774. }
  89775. return $buffer;
  89776. }
  89777. private function writeWithColor(): string
  89778. {
  89779. $buffer = '';
  89780. foreach ($this->elements() as $section => $options) {
  89781. $buffer .= Color::colorize('fg-yellow', "{$section}:") . PHP_EOL;
  89782. if ($section !== 'Usage') {
  89783. $buffer .= PHP_EOL;
  89784. }
  89785. foreach ($options as $option) {
  89786. if (isset($option['spacer'])) {
  89787. $buffer .= PHP_EOL;
  89788. }
  89789. if (isset($option['text'])) {
  89790. $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL;
  89791. }
  89792. if (isset($option['arg'])) {
  89793. $arg = Color::colorize('fg-green', str_pad($option['arg'], $this->lengthOfLongestOptionName));
  89794. $arg = preg_replace_callback('/(<[^>]+>)/', static fn($matches) => Color::colorize('fg-cyan', $matches[0]), $arg);
  89795. $desc = explode(PHP_EOL, wordwrap($option['desc'], $this->columnsAvailableForDescription, PHP_EOL));
  89796. $buffer .= self::LEFT_MARGIN . $arg . ' ' . $desc[0] . PHP_EOL;
  89797. for ($i = 1; $i < count($desc); $i++) {
  89798. $buffer .= str_repeat(' ', $this->lengthOfLongestOptionName + 3) . $desc[$i] . PHP_EOL;
  89799. }
  89800. }
  89801. }
  89802. $buffer .= PHP_EOL;
  89803. }
  89804. return $buffer;
  89805. }
  89806. /**
  89807. * @psalm-return array<non-empty-string, non-empty-list<array{text: non-empty-string}|array{arg: non-empty-string, desc: non-empty-string}|array{spacer: ''}>>
  89808. */
  89809. private function elements(): array
  89810. {
  89811. $elements = ['Usage' => [['text' => 'phpunit [options] <directory|file> ...']], 'Configuration' => [['arg' => '--bootstrap <file>', 'desc' => 'A PHP script that is included before the tests run'], ['arg' => '-c|--configuration <file>', 'desc' => 'Read configuration from XML file'], ['arg' => '--no-configuration', 'desc' => 'Ignore default configuration file (phpunit.xml)'], ['arg' => '--no-extensions', 'desc' => 'Do not load PHPUnit extensions'], ['arg' => '--include-path <path(s)>', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], ['arg' => '-d <key[=value]>', 'desc' => 'Sets a php.ini value'], ['arg' => '--cache-directory <dir>', 'desc' => 'Specify cache directory'], ['arg' => '--generate-configuration', 'desc' => 'Generate configuration file with suggested settings'], ['arg' => '--migrate-configuration', 'desc' => 'Migrate configuration file to current format'], ['arg' => '--generate-baseline <file>', 'desc' => 'Generate baseline for issues'], ['arg' => '--use-baseline <file>', 'desc' => 'Use baseline to ignore issues'], ['arg' => '--ignore-baseline', 'desc' => 'Do not use baseline to ignore issues']], 'Selection' => [['arg' => '--list-suites', 'desc' => 'List available test suites'], ['arg' => '--testsuite <name>', 'desc' => 'Only run tests from the specified test suite(s)'], ['arg' => '--exclude-testsuite <name>', 'desc' => 'Exclude tests from the specified test suite(s)'], ['arg' => '--list-groups', 'desc' => 'List available test groups'], ['arg' => '--group <name>', 'desc' => 'Only run tests from the specified group(s)'], ['arg' => '--exclude-group <name>', 'desc' => 'Exclude tests from the specified group(s)'], ['arg' => '--covers <name>', 'desc' => 'Only run tests that intend to cover <name>'], ['arg' => '--uses <name>', 'desc' => 'Only run tests that intend to use <name>'], ['arg' => '--list-tests', 'desc' => 'List available tests'], ['arg' => '--list-tests-xml <file>', 'desc' => 'List available tests in XML format'], ['arg' => '--filter <pattern>', 'desc' => 'Filter which tests to run'], ['arg' => '--test-suffix <suffixes>', 'desc' => 'Only search for test in files with specified suffix(es). Default: Test.php,.phpt']], 'Execution' => [['arg' => '--process-isolation', 'desc' => 'Run each test in a separate PHP process'], ['arg' => '--globals-backup', 'desc' => 'Backup and restore $GLOBALS for each test'], ['arg' => '--static-backup', 'desc' => 'Backup and restore static properties for each test'], ['spacer' => ''], ['arg' => '--strict-coverage', 'desc' => 'Be strict about code coverage metadata'], ['arg' => '--strict-global-state', 'desc' => 'Be strict about changes to global state'], ['arg' => '--disallow-test-output', 'desc' => 'Be strict about output during tests'], ['arg' => '--enforce-time-limit', 'desc' => 'Enforce time limit based on test size'], ['arg' => '--default-time-limit <sec>', 'desc' => 'Timeout in seconds for tests that have no declared size'], ['arg' => '--dont-report-useless-tests', 'desc' => 'Do not report tests that do not test anything'], ['spacer' => ''], ['arg' => '--stop-on-defect', 'desc' => 'Stop after first error, failure, warning, or risky test'], ['arg' => '--stop-on-error', 'desc' => 'Stop after first error'], ['arg' => '--stop-on-failure', 'desc' => 'Stop after first failure'], ['arg' => '--stop-on-warning', 'desc' => 'Stop after first warning'], ['arg' => '--stop-on-risky', 'desc' => 'Stop after first risky test'], ['arg' => '--stop-on-deprecation', 'desc' => 'Stop after first test that triggered a deprecation'], ['arg' => '--stop-on-notice', 'desc' => 'Stop after first test that triggered a notice'], ['arg' => '--stop-on-skipped', 'desc' => 'Stop after first skipped test'], ['arg' => '--stop-on-incomplete', 'desc' => 'Stop after first incomplete test'], ['spacer' => ''], ['arg' => '--fail-on-empty-test-suite', 'desc' => 'Signal failure using shell exit code when no tests were run'], ['arg' => '--fail-on-warning', 'desc' => 'Signal failure using shell exit code when a warning was triggered'], ['arg' => '--fail-on-risky', 'desc' => 'Signal failure using shell exit code when a test was considered risky'], ['arg' => '--fail-on-deprecation', 'desc' => 'Signal failure using shell exit code when a deprecation was triggered'], ['arg' => '--fail-on-phpunit-deprecation', 'desc' => 'Signal failure using shell exit code when a PHPUnit deprecation was triggered'], ['arg' => '--fail-on-notice', 'desc' => 'Signal failure using shell exit code when a notice was triggered'], ['arg' => '--fail-on-skipped', 'desc' => 'Signal failure using shell exit code when a test was skipped'], ['arg' => '--fail-on-incomplete', 'desc' => 'Signal failure using shell exit code when a test was marked incomplete'], ['spacer' => ''], ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'], ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'], ['spacer' => ''], ['arg' => '--order-by <order>', 'desc' => 'Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size'], ['arg' => '--random-order-seed <N>', 'desc' => 'Use the specified random seed when running tests in random order']], 'Reporting' => [['arg' => '--colors <flag>', 'desc' => 'Use colors in output ("never", "auto" or "always")'], ['arg' => '--columns <n>', 'desc' => 'Number of columns to use for progress output'], ['arg' => '--columns max', 'desc' => 'Use maximum number of columns for progress output'], ['arg' => '--stderr', 'desc' => 'Write to STDERR instead of STDOUT'], ['spacer' => ''], ['arg' => '--no-progress', 'desc' => 'Disable output of test execution progress'], ['arg' => '--no-results', 'desc' => 'Disable output of test results'], ['arg' => '--no-output', 'desc' => 'Disable all output'], ['spacer' => ''], ['arg' => '--display-incomplete', 'desc' => 'Display details for incomplete tests'], ['arg' => '--display-skipped', 'desc' => 'Display details for skipped tests'], ['arg' => '--display-deprecations', 'desc' => 'Display details for deprecations triggered by tests'], ['arg' => '--display-phpunit-deprecations', 'desc' => 'Display details for PHPUnit deprecations'], ['arg' => '--display-errors', 'desc' => 'Display details for errors triggered by tests'], ['arg' => '--display-notices', 'desc' => 'Display details for notices triggered by tests'], ['arg' => '--display-warnings', 'desc' => 'Display details for warnings triggered by tests'], ['arg' => '--reverse-list', 'desc' => 'Print defects in reverse order'], ['spacer' => ''], ['arg' => '--teamcity', 'desc' => 'Replace default progress and result output with TeamCity format'], ['arg' => '--testdox', 'desc' => 'Replace default result output with TestDox format'], ['spacer' => ''], ['arg' => '--debug', 'desc' => 'Replace default progress and result output with debugging information']], 'Logging' => [['arg' => '--log-junit <file>', 'desc' => 'Write test results in JUnit XML format to file'], ['arg' => '--log-teamcity <file>', 'desc' => 'Write test results in TeamCity format to file'], ['arg' => '--testdox-html <file>', 'desc' => 'Write test results in TestDox format (HTML) to file'], ['arg' => '--testdox-text <file>', 'desc' => 'Write test results in TestDox format (plain text) to file'], ['arg' => '--log-events-text <file>', 'desc' => 'Stream events as plain text to file'], ['arg' => '--log-events-verbose-text <file>', 'desc' => 'Stream events as plain text with extended information to file'], ['arg' => '--no-logging', 'desc' => 'Ignore logging configured in the XML configuration file']], 'Code Coverage' => [['arg' => '--coverage-clover <file>', 'desc' => 'Write code coverage report in Clover XML format to file'], ['arg' => '--coverage-cobertura <file>', 'desc' => 'Write code coverage report in Cobertura XML format to file'], ['arg' => '--coverage-crap4j <file>', 'desc' => 'Write code coverage report in Crap4J XML format to file'], ['arg' => '--coverage-html <dir>', 'desc' => 'Write code coverage report in HTML format to directory'], ['arg' => '--coverage-php <file>', 'desc' => 'Write serialized code coverage data to file'], ['arg' => '--coverage-text=<file>', 'desc' => 'Write code coverage report in text format to file [default: standard output]'], ['arg' => '--only-summary-for-coverage-text', 'desc' => 'Option for code coverage report in text format: only show summary'], ['arg' => '--show-uncovered-for-coverage-text', 'desc' => 'Option for code coverage report in text format: show uncovered files'], ['arg' => '--coverage-xml <dir>', 'desc' => 'Write code coverage report in XML format to directory'], ['arg' => '--warm-coverage-cache', 'desc' => 'Warm static analysis cache'], ['arg' => '--coverage-filter <dir>', 'desc' => 'Include <dir> in code coverage reporting'], ['arg' => '--path-coverage', 'desc' => 'Report path coverage in addition to line coverage'], ['arg' => '--disable-coverage-ignore', 'desc' => 'Disable metadata for ignoring code coverage'], ['arg' => '--no-coverage', 'desc' => 'Ignore code coverage reporting configured in the XML configuration file']]];
  89812. if (defined('__PHPUNIT_PHAR__')) {
  89813. $elements['PHAR'] = [['arg' => '--manifest', 'desc' => 'Print Software Bill of Materials (SBOM) in plain-text format'], ['arg' => '--sbom', 'desc' => 'Print Software Bill of Materials (SBOM) in CycloneDX XML format'], ['arg' => '--composer-lock', 'desc' => 'Print composer.lock file used to build the PHAR']];
  89814. }
  89815. $elements['Miscellaneous'] = [['arg' => '-h|--help', 'desc' => 'Prints this usage information'], ['arg' => '--version', 'desc' => 'Prints the version and exits'], ['arg' => '--atleast-version <min>', 'desc' => 'Checks that version is greater than <min> and exits'], ['arg' => '--check-version', 'desc' => 'Checks whether PHPUnit is the latest version and exits']];
  89816. return $elements;
  89817. }
  89818. }
  89819. <?php
  89820. declare (strict_types=1);
  89821. /*
  89822. * This file is part of PHPUnit.
  89823. *
  89824. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  89825. *
  89826. * For the full copyright and license information, please view the LICENSE
  89827. * file that was distributed with this source code.
  89828. */
  89829. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  89830. use function floor;
  89831. use function sprintf;
  89832. use function str_contains;
  89833. use function str_repeat;
  89834. use function strlen;
  89835. use PHPUnit\Event\EventFacadeIsSealedException;
  89836. use PHPUnit\Event\Facade;
  89837. use PHPUnit\Event\Test\DeprecationTriggered;
  89838. use PHPUnit\Event\Test\Errored;
  89839. use PHPUnit\Event\Test\ErrorTriggered;
  89840. use PHPUnit\Event\Test\NoticeTriggered;
  89841. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  89842. use PHPUnit\Event\Test\PhpNoticeTriggered;
  89843. use PHPUnit\Event\Test\PhpWarningTriggered;
  89844. use PHPUnit\Event\Test\WarningTriggered;
  89845. use PHPUnit\Event\TestRunner\ExecutionStarted;
  89846. use PHPUnit\Event\UnknownSubscriberTypeException;
  89847. use PHPUnit\Framework\TestStatus\TestStatus;
  89848. use PHPUnit\TextUI\Configuration\Source;
  89849. use PHPUnit\TextUI\Configuration\SourceFilter;
  89850. use PHPUnit\TextUI\Output\Printer;
  89851. use PHPUnit\Util\Color;
  89852. /**
  89853. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  89854. *
  89855. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  89856. */
  89857. final class ProgressPrinter
  89858. {
  89859. private readonly Printer $printer;
  89860. private readonly bool $colors;
  89861. private readonly int $numberOfColumns;
  89862. private readonly Source $source;
  89863. private int $column = 0;
  89864. private int $numberOfTests = 0;
  89865. private int $numberOfTestsWidth = 0;
  89866. private int $maxColumn = 0;
  89867. private int $numberOfTestsRun = 0;
  89868. private ?TestStatus $status = null;
  89869. private bool $prepared = \false;
  89870. /**
  89871. * @throws EventFacadeIsSealedException
  89872. * @throws UnknownSubscriberTypeException
  89873. */
  89874. public function __construct(Printer $printer, Facade $facade, bool $colors, int $numberOfColumns, Source $source)
  89875. {
  89876. $this->printer = $printer;
  89877. $this->colors = $colors;
  89878. $this->numberOfColumns = $numberOfColumns;
  89879. $this->source = $source;
  89880. $this->registerSubscribers($facade);
  89881. }
  89882. public function testRunnerExecutionStarted(ExecutionStarted $event): void
  89883. {
  89884. $this->numberOfTestsRun = 0;
  89885. $this->numberOfTests = $event->testSuite()->count();
  89886. $this->numberOfTestsWidth = strlen((string) $this->numberOfTests);
  89887. $this->column = 0;
  89888. $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - 2 * $this->numberOfTestsWidth;
  89889. }
  89890. public function beforeTestClassMethodErrored(): void
  89891. {
  89892. $this->printProgressForError();
  89893. $this->updateTestStatus(TestStatus::error());
  89894. }
  89895. public function testPrepared(): void
  89896. {
  89897. $this->prepared = \true;
  89898. }
  89899. public function testSkipped(): void
  89900. {
  89901. if (!$this->prepared) {
  89902. $this->printProgressForSkipped();
  89903. } else {
  89904. $this->updateTestStatus(TestStatus::skipped());
  89905. }
  89906. }
  89907. public function testMarkedIncomplete(): void
  89908. {
  89909. $this->updateTestStatus(TestStatus::incomplete());
  89910. }
  89911. public function testTriggeredNotice(NoticeTriggered $event): void
  89912. {
  89913. if ($event->ignoredByBaseline()) {
  89914. return;
  89915. }
  89916. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89917. return;
  89918. }
  89919. if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
  89920. return;
  89921. }
  89922. $this->updateTestStatus(TestStatus::notice());
  89923. }
  89924. public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
  89925. {
  89926. if ($event->ignoredByBaseline()) {
  89927. return;
  89928. }
  89929. if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89930. return;
  89931. }
  89932. if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
  89933. return;
  89934. }
  89935. $this->updateTestStatus(TestStatus::notice());
  89936. }
  89937. public function testTriggeredDeprecation(DeprecationTriggered $event): void
  89938. {
  89939. if ($event->ignoredByBaseline() || $event->ignoredByTest()) {
  89940. return;
  89941. }
  89942. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89943. return;
  89944. }
  89945. if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
  89946. return;
  89947. }
  89948. $this->updateTestStatus(TestStatus::deprecation());
  89949. }
  89950. public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
  89951. {
  89952. if ($event->ignoredByBaseline() || $event->ignoredByTest()) {
  89953. return;
  89954. }
  89955. if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89956. return;
  89957. }
  89958. if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
  89959. return;
  89960. }
  89961. $this->updateTestStatus(TestStatus::deprecation());
  89962. }
  89963. public function testTriggeredPhpunitDeprecation(): void
  89964. {
  89965. $this->updateTestStatus(TestStatus::deprecation());
  89966. }
  89967. public function testConsideredRisky(): void
  89968. {
  89969. $this->updateTestStatus(TestStatus::risky());
  89970. }
  89971. public function testTriggeredWarning(WarningTriggered $event): void
  89972. {
  89973. if ($event->ignoredByBaseline()) {
  89974. return;
  89975. }
  89976. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89977. return;
  89978. }
  89979. if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
  89980. return;
  89981. }
  89982. $this->updateTestStatus(TestStatus::warning());
  89983. }
  89984. public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
  89985. {
  89986. if ($event->ignoredByBaseline()) {
  89987. return;
  89988. }
  89989. if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) {
  89990. return;
  89991. }
  89992. if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
  89993. return;
  89994. }
  89995. $this->updateTestStatus(TestStatus::warning());
  89996. }
  89997. public function testTriggeredPhpunitWarning(): void
  89998. {
  89999. $this->updateTestStatus(TestStatus::warning());
  90000. }
  90001. public function testTriggeredError(ErrorTriggered $event): void
  90002. {
  90003. if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) {
  90004. return;
  90005. }
  90006. $this->updateTestStatus(TestStatus::error());
  90007. }
  90008. public function testFailed(): void
  90009. {
  90010. $this->updateTestStatus(TestStatus::failure());
  90011. }
  90012. public function testErrored(Errored $event): void
  90013. {
  90014. /*
  90015. * @todo Eliminate this special case
  90016. */
  90017. if (str_contains($event->asString(), 'Test was run in child process and ended unexpectedly')) {
  90018. $this->updateTestStatus(TestStatus::error());
  90019. return;
  90020. }
  90021. if (!$this->prepared) {
  90022. $this->printProgressForError();
  90023. } else {
  90024. $this->updateTestStatus(TestStatus::error());
  90025. }
  90026. }
  90027. public function testFinished(): void
  90028. {
  90029. if ($this->status === null) {
  90030. $this->printProgressForSuccess();
  90031. } elseif ($this->status->isSkipped()) {
  90032. $this->printProgressForSkipped();
  90033. } elseif ($this->status->isIncomplete()) {
  90034. $this->printProgressForIncomplete();
  90035. } elseif ($this->status->isRisky()) {
  90036. $this->printProgressForRisky();
  90037. } elseif ($this->status->isNotice()) {
  90038. $this->printProgressForNotice();
  90039. } elseif ($this->status->isDeprecation()) {
  90040. $this->printProgressForDeprecation();
  90041. } elseif ($this->status->isWarning()) {
  90042. $this->printProgressForWarning();
  90043. } elseif ($this->status->isFailure()) {
  90044. $this->printProgressForFailure();
  90045. } else {
  90046. $this->printProgressForError();
  90047. }
  90048. $this->status = null;
  90049. $this->prepared = \false;
  90050. }
  90051. /**
  90052. * @throws EventFacadeIsSealedException
  90053. * @throws UnknownSubscriberTypeException
  90054. */
  90055. private function registerSubscribers(Facade $facade): void
  90056. {
  90057. $facade->registerSubscribers(new \PHPUnit\TextUI\Output\Default\ProgressPrinter\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestConsideredRiskySubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFailedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFinishedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestPreparedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestRunnerExecutionStartedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestSkippedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredWarningSubscriber($this));
  90058. }
  90059. private function updateTestStatus(TestStatus $status): void
  90060. {
  90061. if ($this->status !== null && $this->status->isMoreImportantThan($status)) {
  90062. return;
  90063. }
  90064. $this->status = $status;
  90065. }
  90066. private function printProgressForSuccess(): void
  90067. {
  90068. $this->printProgress('.');
  90069. }
  90070. private function printProgressForSkipped(): void
  90071. {
  90072. $this->printProgressWithColor('fg-cyan, bold', 'S');
  90073. }
  90074. private function printProgressForIncomplete(): void
  90075. {
  90076. $this->printProgressWithColor('fg-yellow, bold', 'I');
  90077. }
  90078. private function printProgressForNotice(): void
  90079. {
  90080. $this->printProgressWithColor('fg-yellow, bold', 'N');
  90081. }
  90082. private function printProgressForDeprecation(): void
  90083. {
  90084. $this->printProgressWithColor('fg-yellow, bold', 'D');
  90085. }
  90086. private function printProgressForRisky(): void
  90087. {
  90088. $this->printProgressWithColor('fg-yellow, bold', 'R');
  90089. }
  90090. private function printProgressForWarning(): void
  90091. {
  90092. $this->printProgressWithColor('fg-yellow, bold', 'W');
  90093. }
  90094. private function printProgressForFailure(): void
  90095. {
  90096. $this->printProgressWithColor('bg-red, fg-white', 'F');
  90097. }
  90098. private function printProgressForError(): void
  90099. {
  90100. $this->printProgressWithColor('fg-red, bold', 'E');
  90101. }
  90102. private function printProgressWithColor(string $color, string $progress): void
  90103. {
  90104. if ($this->colors) {
  90105. $progress = Color::colorizeTextBox($color, $progress);
  90106. }
  90107. $this->printProgress($progress);
  90108. }
  90109. private function printProgress(string $progress): void
  90110. {
  90111. $this->printer->print($progress);
  90112. $this->column++;
  90113. $this->numberOfTestsRun++;
  90114. if ($this->column === $this->maxColumn || $this->numberOfTestsRun === $this->numberOfTests) {
  90115. if ($this->numberOfTestsRun === $this->numberOfTests) {
  90116. $this->printer->print(str_repeat(' ', $this->maxColumn - $this->column));
  90117. }
  90118. $this->printer->print(sprintf(' %' . $this->numberOfTestsWidth . 'd / %' . $this->numberOfTestsWidth . 'd (%3s%%)', $this->numberOfTestsRun, $this->numberOfTests, floor($this->numberOfTestsRun / $this->numberOfTests * 100)));
  90119. if ($this->column === $this->maxColumn) {
  90120. $this->column = 0;
  90121. $this->printer->print("\n");
  90122. }
  90123. }
  90124. }
  90125. }
  90126. <?php
  90127. declare (strict_types=1);
  90128. /*
  90129. * This file is part of PHPUnit.
  90130. *
  90131. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90132. *
  90133. * For the full copyright and license information, please view the LICENSE
  90134. * file that was distributed with this source code.
  90135. */
  90136. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90137. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  90138. use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
  90139. /**
  90140. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90141. *
  90142. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90143. */
  90144. final class BeforeTestClassMethodErroredSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements BeforeFirstTestMethodErroredSubscriber
  90145. {
  90146. public function notify(BeforeFirstTestMethodErrored $event): void
  90147. {
  90148. $this->printer()->beforeTestClassMethodErrored();
  90149. }
  90150. }
  90151. <?php
  90152. declare (strict_types=1);
  90153. /*
  90154. * This file is part of PHPUnit.
  90155. *
  90156. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90157. *
  90158. * For the full copyright and license information, please view the LICENSE
  90159. * file that was distributed with this source code.
  90160. */
  90161. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90162. /**
  90163. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90164. *
  90165. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90166. */
  90167. abstract class Subscriber
  90168. {
  90169. private readonly \PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter $printer;
  90170. public function __construct(\PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter $printer)
  90171. {
  90172. $this->printer = $printer;
  90173. }
  90174. protected function printer(): \PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter
  90175. {
  90176. return $this->printer;
  90177. }
  90178. }
  90179. <?php
  90180. declare (strict_types=1);
  90181. /*
  90182. * This file is part of PHPUnit.
  90183. *
  90184. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90185. *
  90186. * For the full copyright and license information, please view the LICENSE
  90187. * file that was distributed with this source code.
  90188. */
  90189. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90190. use PHPUnit\Event\Test\ConsideredRisky;
  90191. use PHPUnit\Event\Test\ConsideredRiskySubscriber;
  90192. /**
  90193. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90194. *
  90195. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90196. */
  90197. final class TestConsideredRiskySubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ConsideredRiskySubscriber
  90198. {
  90199. public function notify(ConsideredRisky $event): void
  90200. {
  90201. $this->printer()->testConsideredRisky();
  90202. }
  90203. }
  90204. <?php
  90205. declare (strict_types=1);
  90206. /*
  90207. * This file is part of PHPUnit.
  90208. *
  90209. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90210. *
  90211. * For the full copyright and license information, please view the LICENSE
  90212. * file that was distributed with this source code.
  90213. */
  90214. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90215. use PHPUnit\Event\Test\Errored;
  90216. use PHPUnit\Event\Test\ErroredSubscriber;
  90217. /**
  90218. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90219. *
  90220. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90221. */
  90222. final class TestErroredSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ErroredSubscriber
  90223. {
  90224. public function notify(Errored $event): void
  90225. {
  90226. $this->printer()->testErrored($event);
  90227. }
  90228. }
  90229. <?php
  90230. declare (strict_types=1);
  90231. /*
  90232. * This file is part of PHPUnit.
  90233. *
  90234. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90235. *
  90236. * For the full copyright and license information, please view the LICENSE
  90237. * file that was distributed with this source code.
  90238. */
  90239. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90240. use PHPUnit\Event\Test\Failed;
  90241. use PHPUnit\Event\Test\FailedSubscriber;
  90242. /**
  90243. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90244. *
  90245. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90246. */
  90247. final class TestFailedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements FailedSubscriber
  90248. {
  90249. public function notify(Failed $event): void
  90250. {
  90251. $this->printer()->testFailed();
  90252. }
  90253. }
  90254. <?php
  90255. declare (strict_types=1);
  90256. /*
  90257. * This file is part of PHPUnit.
  90258. *
  90259. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90260. *
  90261. * For the full copyright and license information, please view the LICENSE
  90262. * file that was distributed with this source code.
  90263. */
  90264. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90265. use PHPUnit\Event\Test\Finished;
  90266. use PHPUnit\Event\Test\FinishedSubscriber;
  90267. /**
  90268. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90269. *
  90270. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90271. */
  90272. final class TestFinishedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements FinishedSubscriber
  90273. {
  90274. public function notify(Finished $event): void
  90275. {
  90276. $this->printer()->testFinished();
  90277. }
  90278. }
  90279. <?php
  90280. declare (strict_types=1);
  90281. /*
  90282. * This file is part of PHPUnit.
  90283. *
  90284. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90285. *
  90286. * For the full copyright and license information, please view the LICENSE
  90287. * file that was distributed with this source code.
  90288. */
  90289. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90290. use PHPUnit\Event\Test\MarkedIncomplete;
  90291. use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
  90292. /**
  90293. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90294. *
  90295. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90296. */
  90297. final class TestMarkedIncompleteSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements MarkedIncompleteSubscriber
  90298. {
  90299. public function notify(MarkedIncomplete $event): void
  90300. {
  90301. $this->printer()->testMarkedIncomplete();
  90302. }
  90303. }
  90304. <?php
  90305. declare (strict_types=1);
  90306. /*
  90307. * This file is part of PHPUnit.
  90308. *
  90309. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90310. *
  90311. * For the full copyright and license information, please view the LICENSE
  90312. * file that was distributed with this source code.
  90313. */
  90314. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90315. use PHPUnit\Event\Test\Prepared;
  90316. use PHPUnit\Event\Test\PreparedSubscriber;
  90317. /**
  90318. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90319. *
  90320. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90321. */
  90322. final class TestPreparedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PreparedSubscriber
  90323. {
  90324. public function notify(Prepared $event): void
  90325. {
  90326. $this->printer()->testPrepared();
  90327. }
  90328. }
  90329. <?php
  90330. declare (strict_types=1);
  90331. /*
  90332. * This file is part of PHPUnit.
  90333. *
  90334. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90335. *
  90336. * For the full copyright and license information, please view the LICENSE
  90337. * file that was distributed with this source code.
  90338. */
  90339. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90340. use PHPUnit\Event\TestRunner\ExecutionStarted;
  90341. use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber;
  90342. /**
  90343. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90344. *
  90345. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90346. */
  90347. final class TestRunnerExecutionStartedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ExecutionStartedSubscriber
  90348. {
  90349. public function notify(ExecutionStarted $event): void
  90350. {
  90351. $this->printer()->testRunnerExecutionStarted($event);
  90352. }
  90353. }
  90354. <?php
  90355. declare (strict_types=1);
  90356. /*
  90357. * This file is part of PHPUnit.
  90358. *
  90359. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90360. *
  90361. * For the full copyright and license information, please view the LICENSE
  90362. * file that was distributed with this source code.
  90363. */
  90364. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90365. use PHPUnit\Event\Test\Skipped;
  90366. use PHPUnit\Event\Test\SkippedSubscriber;
  90367. /**
  90368. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90369. *
  90370. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90371. */
  90372. final class TestSkippedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements SkippedSubscriber
  90373. {
  90374. public function notify(Skipped $event): void
  90375. {
  90376. $this->printer()->testSkipped();
  90377. }
  90378. }
  90379. <?php
  90380. declare (strict_types=1);
  90381. /*
  90382. * This file is part of PHPUnit.
  90383. *
  90384. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90385. *
  90386. * For the full copyright and license information, please view the LICENSE
  90387. * file that was distributed with this source code.
  90388. */
  90389. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90390. use PHPUnit\Event\Test\DeprecationTriggered;
  90391. use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
  90392. /**
  90393. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90394. *
  90395. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90396. */
  90397. final class TestTriggeredDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements DeprecationTriggeredSubscriber
  90398. {
  90399. public function notify(DeprecationTriggered $event): void
  90400. {
  90401. $this->printer()->testTriggeredDeprecation($event);
  90402. }
  90403. }
  90404. <?php
  90405. declare (strict_types=1);
  90406. /*
  90407. * This file is part of PHPUnit.
  90408. *
  90409. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90410. *
  90411. * For the full copyright and license information, please view the LICENSE
  90412. * file that was distributed with this source code.
  90413. */
  90414. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90415. use PHPUnit\Event\Test\ErrorTriggered;
  90416. use PHPUnit\Event\Test\ErrorTriggeredSubscriber;
  90417. /**
  90418. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90419. *
  90420. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90421. */
  90422. final class TestTriggeredErrorSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ErrorTriggeredSubscriber
  90423. {
  90424. public function notify(ErrorTriggered $event): void
  90425. {
  90426. $this->printer()->testTriggeredError($event);
  90427. }
  90428. }
  90429. <?php
  90430. declare (strict_types=1);
  90431. /*
  90432. * This file is part of PHPUnit.
  90433. *
  90434. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90435. *
  90436. * For the full copyright and license information, please view the LICENSE
  90437. * file that was distributed with this source code.
  90438. */
  90439. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90440. use PHPUnit\Event\Test\NoticeTriggered;
  90441. use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
  90442. /**
  90443. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90444. *
  90445. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90446. */
  90447. final class TestTriggeredNoticeSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements NoticeTriggeredSubscriber
  90448. {
  90449. public function notify(NoticeTriggered $event): void
  90450. {
  90451. $this->printer()->testTriggeredNotice($event);
  90452. }
  90453. }
  90454. <?php
  90455. declare (strict_types=1);
  90456. /*
  90457. * This file is part of PHPUnit.
  90458. *
  90459. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90460. *
  90461. * For the full copyright and license information, please view the LICENSE
  90462. * file that was distributed with this source code.
  90463. */
  90464. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90465. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  90466. use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
  90467. /**
  90468. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90469. *
  90470. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90471. */
  90472. final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpDeprecationTriggeredSubscriber
  90473. {
  90474. public function notify(PhpDeprecationTriggered $event): void
  90475. {
  90476. $this->printer()->testTriggeredPhpDeprecation($event);
  90477. }
  90478. }
  90479. <?php
  90480. declare (strict_types=1);
  90481. /*
  90482. * This file is part of PHPUnit.
  90483. *
  90484. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90485. *
  90486. * For the full copyright and license information, please view the LICENSE
  90487. * file that was distributed with this source code.
  90488. */
  90489. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90490. use PHPUnit\Event\Test\PhpNoticeTriggered;
  90491. use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
  90492. /**
  90493. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90494. *
  90495. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90496. */
  90497. final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpNoticeTriggeredSubscriber
  90498. {
  90499. public function notify(PhpNoticeTriggered $event): void
  90500. {
  90501. $this->printer()->testTriggeredPhpNotice($event);
  90502. }
  90503. }
  90504. <?php
  90505. declare (strict_types=1);
  90506. /*
  90507. * This file is part of PHPUnit.
  90508. *
  90509. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90510. *
  90511. * For the full copyright and license information, please view the LICENSE
  90512. * file that was distributed with this source code.
  90513. */
  90514. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90515. use PHPUnit\Event\Test\PhpWarningTriggered;
  90516. use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
  90517. /**
  90518. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90519. *
  90520. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90521. */
  90522. final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpWarningTriggeredSubscriber
  90523. {
  90524. public function notify(PhpWarningTriggered $event): void
  90525. {
  90526. $this->printer()->testTriggeredPhpWarning($event);
  90527. }
  90528. }
  90529. <?php
  90530. declare (strict_types=1);
  90531. /*
  90532. * This file is part of PHPUnit.
  90533. *
  90534. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90535. *
  90536. * For the full copyright and license information, please view the LICENSE
  90537. * file that was distributed with this source code.
  90538. */
  90539. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90540. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  90541. use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
  90542. /**
  90543. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90544. *
  90545. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90546. */
  90547. final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpunitDeprecationTriggeredSubscriber
  90548. {
  90549. public function notify(PhpunitDeprecationTriggered $event): void
  90550. {
  90551. $this->printer()->testTriggeredPhpunitDeprecation();
  90552. }
  90553. }
  90554. <?php
  90555. declare (strict_types=1);
  90556. /*
  90557. * This file is part of PHPUnit.
  90558. *
  90559. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90560. *
  90561. * For the full copyright and license information, please view the LICENSE
  90562. * file that was distributed with this source code.
  90563. */
  90564. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90565. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  90566. use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
  90567. /**
  90568. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90569. *
  90570. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90571. */
  90572. final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpunitWarningTriggeredSubscriber
  90573. {
  90574. public function notify(PhpunitWarningTriggered $event): void
  90575. {
  90576. $this->printer()->testTriggeredPhpunitWarning();
  90577. }
  90578. }
  90579. <?php
  90580. declare (strict_types=1);
  90581. /*
  90582. * This file is part of PHPUnit.
  90583. *
  90584. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90585. *
  90586. * For the full copyright and license information, please view the LICENSE
  90587. * file that was distributed with this source code.
  90588. */
  90589. namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
  90590. use PHPUnit\Event\Test\WarningTriggered;
  90591. use PHPUnit\Event\Test\WarningTriggeredSubscriber;
  90592. /**
  90593. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90594. *
  90595. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90596. */
  90597. final class TestTriggeredWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements WarningTriggeredSubscriber
  90598. {
  90599. public function notify(WarningTriggered $event): void
  90600. {
  90601. $this->printer()->testTriggeredWarning($event);
  90602. }
  90603. }
  90604. <?php
  90605. declare (strict_types=1);
  90606. /*
  90607. * This file is part of PHPUnit.
  90608. *
  90609. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  90610. *
  90611. * For the full copyright and license information, please view the LICENSE
  90612. * file that was distributed with this source code.
  90613. */
  90614. namespace PHPUnit\TextUI\Output\Default;
  90615. use const PHP_EOL;
  90616. use function array_keys;
  90617. use function array_merge;
  90618. use function array_reverse;
  90619. use function array_unique;
  90620. use function assert;
  90621. use function count;
  90622. use function explode;
  90623. use function ksort;
  90624. use function range;
  90625. use function sprintf;
  90626. use function str_starts_with;
  90627. use function strlen;
  90628. use function substr;
  90629. use function trim;
  90630. use PHPUnit\Event\Code\Test;
  90631. use PHPUnit\Event\Code\TestMethod;
  90632. use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
  90633. use PHPUnit\Event\Test\ConsideredRisky;
  90634. use PHPUnit\Event\Test\DeprecationTriggered;
  90635. use PHPUnit\Event\Test\ErrorTriggered;
  90636. use PHPUnit\Event\Test\NoticeTriggered;
  90637. use PHPUnit\Event\Test\PhpDeprecationTriggered;
  90638. use PHPUnit\Event\Test\PhpNoticeTriggered;
  90639. use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
  90640. use PHPUnit\Event\Test\PhpunitErrorTriggered;
  90641. use PHPUnit\Event\Test\PhpunitWarningTriggered;
  90642. use PHPUnit\Event\Test\PhpWarningTriggered;
  90643. use PHPUnit\Event\Test\WarningTriggered;
  90644. use PHPUnit\TestRunner\TestResult\Issues\Issue;
  90645. use PHPUnit\TestRunner\TestResult\TestResult;
  90646. use PHPUnit\TextUI\Output\Printer;
  90647. /**
  90648. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  90649. *
  90650. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  90651. */
  90652. final class ResultPrinter
  90653. {
  90654. private readonly Printer $printer;
  90655. private readonly bool $displayPhpunitErrors;
  90656. private readonly bool $displayPhpunitWarnings;
  90657. private readonly bool $displayTestsWithErrors;
  90658. private readonly bool $displayTestsWithFailedAssertions;
  90659. private readonly bool $displayRiskyTests;
  90660. private readonly bool $displayPhpunitDeprecations;
  90661. private readonly bool $displayDetailsOnIncompleteTests;
  90662. private readonly bool $displayDetailsOnSkippedTests;
  90663. private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
  90664. private readonly bool $displayDetailsOnTestsThatTriggerErrors;
  90665. private readonly bool $displayDetailsOnTestsThatTriggerNotices;
  90666. private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
  90667. private readonly bool $displayDefectsInReverseOrder;
  90668. private bool $listPrinted = \false;
  90669. public function __construct(Printer $printer, bool $displayPhpunitErrors, bool $displayPhpunitWarnings, bool $displayPhpunitDeprecations, bool $displayTestsWithErrors, bool $displayTestsWithFailedAssertions, bool $displayRiskyTests, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $displayDefectsInReverseOrder)
  90670. {
  90671. $this->printer = $printer;
  90672. $this->displayPhpunitErrors = $displayPhpunitErrors;
  90673. $this->displayPhpunitWarnings = $displayPhpunitWarnings;
  90674. $this->displayPhpunitDeprecations = $displayPhpunitDeprecations;
  90675. $this->displayTestsWithErrors = $displayTestsWithErrors;
  90676. $this->displayTestsWithFailedAssertions = $displayTestsWithFailedAssertions;
  90677. $this->displayRiskyTests = $displayRiskyTests;
  90678. $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
  90679. $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
  90680. $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
  90681. $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
  90682. $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
  90683. $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
  90684. $this->displayDefectsInReverseOrder = $displayDefectsInReverseOrder;
  90685. }
  90686. public function print(TestResult $result): void
  90687. {
  90688. if ($this->displayPhpunitErrors) {
  90689. $this->printPhpunitErrors($result);
  90690. }
  90691. if ($this->displayPhpunitWarnings) {
  90692. $this->printTestRunnerWarnings($result);
  90693. }
  90694. if ($this->displayPhpunitDeprecations) {
  90695. $this->printTestRunnerDeprecations($result);
  90696. }
  90697. if ($this->displayTestsWithErrors) {
  90698. $this->printTestsWithErrors($result);
  90699. }
  90700. if ($this->displayTestsWithFailedAssertions) {
  90701. $this->printTestsWithFailedAssertions($result);
  90702. }
  90703. if ($this->displayPhpunitWarnings) {
  90704. $this->printDetailsOnTestsThatTriggeredPhpunitWarnings($result);
  90705. }
  90706. if ($this->displayPhpunitDeprecations) {
  90707. $this->printDetailsOnTestsThatTriggeredPhpunitDeprecations($result);
  90708. }
  90709. if ($this->displayRiskyTests) {
  90710. $this->printRiskyTests($result);
  90711. }
  90712. if ($this->displayDetailsOnIncompleteTests) {
  90713. $this->printIncompleteTests($result);
  90714. }
  90715. if ($this->displayDetailsOnSkippedTests) {
  90716. $this->printSkippedTestSuites($result);
  90717. $this->printSkippedTests($result);
  90718. }
  90719. if ($this->displayDetailsOnTestsThatTriggerErrors) {
  90720. $this->printIssueList('error', $result->errors());
  90721. }
  90722. if ($this->displayDetailsOnTestsThatTriggerWarnings) {
  90723. $this->printIssueList('PHP warning', $result->phpWarnings());
  90724. $this->printIssueList('warning', $result->warnings());
  90725. }
  90726. if ($this->displayDetailsOnTestsThatTriggerNotices) {
  90727. $this->printIssueList('PHP notice', $result->phpNotices());
  90728. $this->printIssueList('notice', $result->notices());
  90729. }
  90730. if ($this->displayDetailsOnTestsThatTriggerDeprecations) {
  90731. $this->printIssueList('PHP deprecation', $result->phpDeprecations());
  90732. $this->printIssueList('deprecation', $result->deprecations());
  90733. }
  90734. }
  90735. private function printPhpunitErrors(TestResult $result): void
  90736. {
  90737. if (!$result->hasTestTriggeredPhpunitErrorEvents()) {
  90738. return;
  90739. }
  90740. $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitErrorEvents());
  90741. $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'PHPUnit error');
  90742. $this->printList($elements['elements']);
  90743. }
  90744. private function printDetailsOnTestsThatTriggeredPhpunitDeprecations(TestResult $result): void
  90745. {
  90746. if (!$result->hasTestTriggeredPhpunitDeprecationEvents()) {
  90747. return;
  90748. }
  90749. $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitDeprecationEvents());
  90750. $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit deprecation');
  90751. $this->printList($elements['elements']);
  90752. }
  90753. private function printTestRunnerWarnings(TestResult $result): void
  90754. {
  90755. if (!$result->hasTestRunnerTriggeredWarningEvents()) {
  90756. return;
  90757. }
  90758. $elements = [];
  90759. foreach ($result->testRunnerTriggeredWarningEvents() as $event) {
  90760. $elements[] = ['title' => $event->message(), 'body' => ''];
  90761. }
  90762. $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner warning');
  90763. $this->printList($elements);
  90764. }
  90765. private function printTestRunnerDeprecations(TestResult $result): void
  90766. {
  90767. if (!$result->hasTestRunnerTriggeredDeprecationEvents()) {
  90768. return;
  90769. }
  90770. $elements = [];
  90771. foreach ($result->testRunnerTriggeredDeprecationEvents() as $event) {
  90772. $elements[] = ['title' => $event->message(), 'body' => ''];
  90773. }
  90774. $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner deprecation');
  90775. $this->printList($elements);
  90776. }
  90777. private function printDetailsOnTestsThatTriggeredPhpunitWarnings(TestResult $result): void
  90778. {
  90779. if (!$result->hasTestTriggeredPhpunitWarningEvents()) {
  90780. return;
  90781. }
  90782. $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitWarningEvents());
  90783. $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit warning');
  90784. $this->printList($elements['elements']);
  90785. }
  90786. private function printTestsWithErrors(TestResult $result): void
  90787. {
  90788. if (!$result->hasTestErroredEvents()) {
  90789. return;
  90790. }
  90791. $elements = [];
  90792. foreach ($result->testErroredEvents() as $event) {
  90793. if ($event instanceof BeforeFirstTestMethodErrored) {
  90794. $title = $event->testClassName();
  90795. } else {
  90796. $title = $this->name($event->test());
  90797. }
  90798. $elements[] = ['title' => $title, 'body' => $event->throwable()->asString()];
  90799. }
  90800. $this->printListHeaderWithNumber(count($elements), 'error');
  90801. $this->printList($elements);
  90802. }
  90803. private function printTestsWithFailedAssertions(TestResult $result): void
  90804. {
  90805. if (!$result->hasTestFailedEvents()) {
  90806. return;
  90807. }
  90808. $elements = [];
  90809. foreach ($result->testFailedEvents() as $event) {
  90810. $body = $event->throwable()->asString();
  90811. if (str_starts_with($body, 'AssertionError: ')) {
  90812. $body = substr($body, strlen('AssertionError: '));
  90813. }
  90814. $elements[] = ['title' => $this->name($event->test()), 'body' => $body];
  90815. }
  90816. $this->printListHeaderWithNumber(count($elements), 'failure');
  90817. $this->printList($elements);
  90818. }
  90819. private function printRiskyTests(TestResult $result): void
  90820. {
  90821. if (!$result->hasTestConsideredRiskyEvents()) {
  90822. return;
  90823. }
  90824. $elements = $this->mapTestsWithIssuesEventsToElements($result->testConsideredRiskyEvents());
  90825. $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'risky test');
  90826. $this->printList($elements['elements']);
  90827. }
  90828. private function printIncompleteTests(TestResult $result): void
  90829. {
  90830. if (!$result->hasTestMarkedIncompleteEvents()) {
  90831. return;
  90832. }
  90833. $elements = [];
  90834. foreach ($result->testMarkedIncompleteEvents() as $event) {
  90835. $elements[] = ['title' => $this->name($event->test()), 'body' => $event->throwable()->asString()];
  90836. }
  90837. $this->printListHeaderWithNumber(count($elements), 'incomplete test');
  90838. $this->printList($elements);
  90839. }
  90840. private function printSkippedTestSuites(TestResult $result): void
  90841. {
  90842. if (!$result->hasTestSuiteSkippedEvents()) {
  90843. return;
  90844. }
  90845. $elements = [];
  90846. foreach ($result->testSuiteSkippedEvents() as $event) {
  90847. $elements[] = ['title' => $event->testSuite()->name(), 'body' => $event->message()];
  90848. }
  90849. $this->printListHeaderWithNumber(count($elements), 'skipped test suite');
  90850. $this->printList($elements);
  90851. }
  90852. private function printSkippedTests(TestResult $result): void
  90853. {
  90854. if (!$result->hasTestSkippedEvents()) {
  90855. return;
  90856. }
  90857. $elements = [];
  90858. foreach ($result->testSkippedEvents() as $event) {
  90859. $elements[] = ['title' => $this->name($event->test()), 'body' => $event->message()];
  90860. }
  90861. $this->printListHeaderWithNumber(count($elements), 'skipped test');
  90862. $this->printList($elements);
  90863. }
  90864. /**
  90865. * @psalm-param non-empty-string $type
  90866. * @psalm-param list<Issue> $issues
  90867. */
  90868. private function printIssueList(string $type, array $issues): void
  90869. {
  90870. if (empty($issues)) {
  90871. return;
  90872. }
  90873. $numberOfUniqueIssues = count($issues);
  90874. $triggeringTests = [];
  90875. foreach ($issues as $issue) {
  90876. $triggeringTests = array_merge($triggeringTests, array_keys($issue->triggeringTests()));
  90877. }
  90878. $numberOfTests = count(array_unique($triggeringTests));
  90879. unset($triggeringTests);
  90880. $this->printListHeader(sprintf('%d test%s triggered %d %s%s:' . PHP_EOL . PHP_EOL, $numberOfTests, $numberOfTests !== 1 ? 's' : '', $numberOfUniqueIssues, $type, $numberOfUniqueIssues !== 1 ? 's' : ''));
  90881. $i = 1;
  90882. foreach ($issues as $issue) {
  90883. $title = sprintf('%s:%d', $issue->file(), $issue->line());
  90884. $body = trim($issue->description()) . PHP_EOL . PHP_EOL . 'Triggered by:';
  90885. $triggeringTests = $issue->triggeringTests();
  90886. ksort($triggeringTests);
  90887. foreach ($triggeringTests as $triggeringTest) {
  90888. $body .= PHP_EOL . PHP_EOL . '* ' . $triggeringTest['test']->id();
  90889. if ($triggeringTest['count'] > 1) {
  90890. $body .= sprintf(' (%d times)', $triggeringTest['count']);
  90891. }
  90892. if ($triggeringTest['test']->isTestMethod()) {
  90893. $body .= PHP_EOL . ' ' . $triggeringTest['test']->file() . ':' . $triggeringTest['test']->line();
  90894. }
  90895. }
  90896. $this->printIssueListElement($i++, $title, $body);
  90897. $this->printer->print(PHP_EOL);
  90898. }
  90899. }
  90900. private function printListHeaderWithNumberOfTestsAndNumberOfIssues(int $numberOfTestsWithIssues, int $numberOfIssues, string $type): void
  90901. {
  90902. $this->printListHeader(sprintf("%d test%s triggered %d %s%s:\n\n", $numberOfTestsWithIssues, $numberOfTestsWithIssues !== 1 ? 's' : '', $numberOfIssues, $type, $numberOfIssues !== 1 ? 's' : ''));
  90903. }
  90904. private function printListHeaderWithNumber(int $number, string $type): void
  90905. {
  90906. $this->printListHeader(sprintf("There %s %d %s%s:\n\n", $number === 1 ? 'was' : 'were', $number, $type, $number === 1 ? '' : 's'));
  90907. }
  90908. private function printListHeader(string $header): void
  90909. {
  90910. if ($this->listPrinted) {
  90911. $this->printer->print("--\n\n");
  90912. }
  90913. $this->listPrinted = \true;
  90914. $this->printer->print($header);
  90915. }
  90916. /**
  90917. * @psalm-param list<array{title: string, body: string}> $elements
  90918. */
  90919. private function printList(array $elements): void
  90920. {
  90921. $i = 1;
  90922. if ($this->displayDefectsInReverseOrder) {
  90923. $elements = array_reverse($elements);
  90924. }
  90925. foreach ($elements as $element) {
  90926. $this->printListElement($i++, $element['title'], $element['body']);
  90927. }
  90928. $this->printer->print("\n");
  90929. }
  90930. private function printListElement(int $number, string $title, string $body): void
  90931. {
  90932. $body = trim($body);
  90933. $this->printer->print(sprintf("%s%d) %s\n%s%s", $number > 1 ? "\n" : '', $number, $title, $body, !empty($body) ? "\n" : ''));
  90934. }
  90935. private function printIssueListElement(int $number, string $title, string $body): void
  90936. {
  90937. $body = trim($body);
  90938. $this->printer->print(sprintf("%d) %s\n%s%s", $number, $title, $body, !empty($body) ? "\n" : ''));
  90939. }
  90940. private function name(Test $test): string
  90941. {
  90942. if ($test->isTestMethod()) {
  90943. assert($test instanceof TestMethod);
  90944. if (!$test->testData()->hasDataFromDataProvider()) {
  90945. return $test->nameWithClass();
  90946. }
  90947. return $test->className() . '::' . $test->methodName() . $test->testData()->dataFromDataProvider()->dataAsStringForResultOutput();
  90948. }
  90949. return $test->name();
  90950. }
  90951. /**
  90952. * @psalm-param array<string,list<ConsideredRisky|DeprecationTriggered|PhpDeprecationTriggered|PhpunitDeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpNoticeTriggered|WarningTriggered|PhpWarningTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered>> $events
  90953. *
  90954. * @psalm-return array{numberOfTestsWithIssues: int, numberOfIssues: int, elements: list<array{title: string, body: string}>}
  90955. */
  90956. private function mapTestsWithIssuesEventsToElements(array $events): array
  90957. {
  90958. $elements = [];
  90959. $issues = 0;
  90960. foreach ($events as $reasons) {
  90961. $test = $reasons[0]->test();
  90962. $testLocation = $this->testLocation($test);
  90963. $title = $this->name($test);
  90964. $body = '';
  90965. $first = \true;
  90966. $single = count($reasons) === 1;
  90967. foreach ($reasons as $reason) {
  90968. if ($first) {
  90969. $first = \false;
  90970. } else {
  90971. $body .= PHP_EOL;
  90972. }
  90973. $body .= $this->reasonMessage($reason, $single);
  90974. $body .= $this->reasonLocation($reason, $single);
  90975. $issues++;
  90976. }
  90977. if (!empty($testLocation)) {
  90978. $body .= $testLocation;
  90979. }
  90980. $elements[] = ['title' => $title, 'body' => $body];
  90981. }
  90982. return ['numberOfTestsWithIssues' => count($events), 'numberOfIssues' => $issues, 'elements' => $elements];
  90983. }
  90984. private function testLocation(Test $test): string
  90985. {
  90986. if (!$test->isTestMethod()) {
  90987. return '';
  90988. }
  90989. assert($test instanceof TestMethod);
  90990. return sprintf('%s%s:%d%s', PHP_EOL, $test->file(), $test->line(), PHP_EOL);
  90991. }
  90992. private function reasonMessage(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string
  90993. {
  90994. $message = trim($reason->message());
  90995. if ($single) {
  90996. return $message . PHP_EOL;
  90997. }
  90998. $lines = explode(PHP_EOL, $message);
  90999. $buffer = '* ' . $lines[0] . PHP_EOL;
  91000. if (count($lines) > 1) {
  91001. foreach (range(1, count($lines) - 1) as $line) {
  91002. $buffer .= ' ' . $lines[$line] . PHP_EOL;
  91003. }
  91004. }
  91005. return $buffer;
  91006. }
  91007. private function reasonLocation(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string
  91008. {
  91009. if (!$reason instanceof DeprecationTriggered && !$reason instanceof PhpDeprecationTriggered && !$reason instanceof ErrorTriggered && !$reason instanceof NoticeTriggered && !$reason instanceof PhpNoticeTriggered && !$reason instanceof WarningTriggered && !$reason instanceof PhpWarningTriggered) {
  91010. return '';
  91011. }
  91012. return sprintf('%s%s:%d%s', $single ? '' : ' ', $reason->file(), $reason->line(), PHP_EOL);
  91013. }
  91014. }
  91015. <?php
  91016. declare (strict_types=1);
  91017. /*
  91018. * This file is part of PHPUnit.
  91019. *
  91020. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91021. *
  91022. * For the full copyright and license information, please view the LICENSE
  91023. * file that was distributed with this source code.
  91024. */
  91025. namespace PHPUnit\TextUI\Output\Default;
  91026. use PHPUnit\Event\EventFacadeIsSealedException;
  91027. use PHPUnit\Event\Facade;
  91028. use PHPUnit\Event\Test\PrintedUnexpectedOutput;
  91029. use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber;
  91030. use PHPUnit\Event\UnknownSubscriberTypeException;
  91031. use PHPUnit\TextUI\Output\Printer;
  91032. final class UnexpectedOutputPrinter implements PrintedUnexpectedOutputSubscriber
  91033. {
  91034. private readonly Printer $printer;
  91035. /**
  91036. * @throws EventFacadeIsSealedException
  91037. * @throws UnknownSubscriberTypeException
  91038. */
  91039. public function __construct(Printer $printer, Facade $facade)
  91040. {
  91041. $this->printer = $printer;
  91042. $facade->registerSubscriber($this);
  91043. }
  91044. public function notify(PrintedUnexpectedOutput $event): void
  91045. {
  91046. $this->printer->print($event->output());
  91047. }
  91048. }
  91049. <?php
  91050. declare (strict_types=1);
  91051. /*
  91052. * This file is part of PHPUnit.
  91053. *
  91054. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91055. *
  91056. * For the full copyright and license information, please view the LICENSE
  91057. * file that was distributed with this source code.
  91058. */
  91059. namespace PHPUnit\TextUI\Output;
  91060. use const PHP_EOL;
  91061. use function assert;
  91062. use PHPUnit\Event\EventFacadeIsSealedException;
  91063. use PHPUnit\Event\Facade as EventFacade;
  91064. use PHPUnit\Event\UnknownSubscriberTypeException;
  91065. use PHPUnit\Logging\TeamCity\TeamCityLogger;
  91066. use PHPUnit\Logging\TestDox\TestResultCollection;
  91067. use PHPUnit\Runner\DirectoryDoesNotExistException;
  91068. use PHPUnit\TestRunner\TestResult\TestResult;
  91069. use PHPUnit\TextUI\CannotOpenSocketException;
  91070. use PHPUnit\TextUI\Configuration\Configuration;
  91071. use PHPUnit\TextUI\InvalidSocketException;
  91072. use PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter as DefaultProgressPrinter;
  91073. use PHPUnit\TextUI\Output\Default\ResultPrinter as DefaultResultPrinter;
  91074. use PHPUnit\TextUI\Output\Default\UnexpectedOutputPrinter;
  91075. use PHPUnit\TextUI\Output\TestDox\ResultPrinter as TestDoxResultPrinter;
  91076. use PHPUnitPHAR\SebastianBergmann\Timer\Duration;
  91077. use PHPUnitPHAR\SebastianBergmann\Timer\ResourceUsageFormatter;
  91078. /**
  91079. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91080. *
  91081. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91082. */
  91083. final class Facade
  91084. {
  91085. private static ?\PHPUnit\TextUI\Output\Printer $printer = null;
  91086. private static ?DefaultResultPrinter $defaultResultPrinter = null;
  91087. private static ?TestDoxResultPrinter $testDoxResultPrinter = null;
  91088. private static ?\PHPUnit\TextUI\Output\SummaryPrinter $summaryPrinter = null;
  91089. private static bool $defaultProgressPrinter = \false;
  91090. /**
  91091. * @throws EventFacadeIsSealedException
  91092. * @throws UnknownSubscriberTypeException
  91093. */
  91094. public static function init(Configuration $configuration, bool $extensionReplacesProgressOutput, bool $extensionReplacesResultOutput): \PHPUnit\TextUI\Output\Printer
  91095. {
  91096. self::createPrinter($configuration);
  91097. assert(self::$printer !== null);
  91098. if ($configuration->debug()) {
  91099. return self::$printer;
  91100. }
  91101. self::createUnexpectedOutputPrinter();
  91102. if (!$extensionReplacesProgressOutput) {
  91103. self::createProgressPrinter($configuration);
  91104. }
  91105. if (!$extensionReplacesResultOutput) {
  91106. self::createResultPrinter($configuration);
  91107. self::createSummaryPrinter($configuration);
  91108. }
  91109. if ($configuration->outputIsTeamCity()) {
  91110. new TeamCityLogger(\PHPUnit\TextUI\Output\DefaultPrinter::standardOutput(), EventFacade::instance());
  91111. }
  91112. return self::$printer;
  91113. }
  91114. /**
  91115. * @psalm-param ?array<string, TestResultCollection> $testDoxResult
  91116. */
  91117. public static function printResult(TestResult $result, ?array $testDoxResult, Duration $duration): void
  91118. {
  91119. assert(self::$printer !== null);
  91120. if ($result->numberOfTestsRun() > 0) {
  91121. if (self::$defaultProgressPrinter) {
  91122. self::$printer->print(PHP_EOL . PHP_EOL);
  91123. }
  91124. self::$printer->print((new ResourceUsageFormatter())->resourceUsage($duration) . PHP_EOL . PHP_EOL);
  91125. }
  91126. if (self::$testDoxResultPrinter !== null && $testDoxResult !== null) {
  91127. self::$testDoxResultPrinter->print($testDoxResult);
  91128. }
  91129. if (self::$defaultResultPrinter !== null) {
  91130. self::$defaultResultPrinter->print($result);
  91131. }
  91132. if (self::$summaryPrinter !== null) {
  91133. self::$summaryPrinter->print($result);
  91134. }
  91135. }
  91136. /**
  91137. * @throws CannotOpenSocketException
  91138. * @throws DirectoryDoesNotExistException
  91139. * @throws InvalidSocketException
  91140. */
  91141. public static function printerFor(string $target): \PHPUnit\TextUI\Output\Printer
  91142. {
  91143. if ($target === 'php://stdout') {
  91144. if (!self::$printer instanceof \PHPUnit\TextUI\Output\NullPrinter) {
  91145. return self::$printer;
  91146. }
  91147. return \PHPUnit\TextUI\Output\DefaultPrinter::standardOutput();
  91148. }
  91149. return \PHPUnit\TextUI\Output\DefaultPrinter::from($target);
  91150. }
  91151. private static function createPrinter(Configuration $configuration): void
  91152. {
  91153. $printerNeeded = \false;
  91154. if ($configuration->debug()) {
  91155. $printerNeeded = \true;
  91156. }
  91157. if ($configuration->outputIsTeamCity()) {
  91158. $printerNeeded = \true;
  91159. }
  91160. if ($configuration->outputIsTestDox()) {
  91161. $printerNeeded = \true;
  91162. }
  91163. if (!$configuration->noOutput() && !$configuration->noProgress()) {
  91164. $printerNeeded = \true;
  91165. }
  91166. if (!$configuration->noOutput() && !$configuration->noResults()) {
  91167. $printerNeeded = \true;
  91168. }
  91169. if ($printerNeeded) {
  91170. if ($configuration->outputToStandardErrorStream()) {
  91171. self::$printer = \PHPUnit\TextUI\Output\DefaultPrinter::standardError();
  91172. return;
  91173. }
  91174. self::$printer = \PHPUnit\TextUI\Output\DefaultPrinter::standardOutput();
  91175. return;
  91176. }
  91177. self::$printer = new \PHPUnit\TextUI\Output\NullPrinter();
  91178. }
  91179. private static function createProgressPrinter(Configuration $configuration): void
  91180. {
  91181. assert(self::$printer !== null);
  91182. if (!self::useDefaultProgressPrinter($configuration)) {
  91183. return;
  91184. }
  91185. new DefaultProgressPrinter(self::$printer, EventFacade::instance(), $configuration->colors(), $configuration->columns(), $configuration->source());
  91186. self::$defaultProgressPrinter = \true;
  91187. }
  91188. private static function useDefaultProgressPrinter(Configuration $configuration): bool
  91189. {
  91190. if ($configuration->noOutput()) {
  91191. return \false;
  91192. }
  91193. if ($configuration->noProgress()) {
  91194. return \false;
  91195. }
  91196. if ($configuration->outputIsTeamCity()) {
  91197. return \false;
  91198. }
  91199. return \true;
  91200. }
  91201. private static function createResultPrinter(Configuration $configuration): void
  91202. {
  91203. assert(self::$printer !== null);
  91204. if ($configuration->outputIsTestDox()) {
  91205. self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, $configuration->displayDetailsOnPhpunitDeprecations(), \false, \false, \true, \false, \false, $configuration->displayDetailsOnTestsThatTriggerDeprecations(), $configuration->displayDetailsOnTestsThatTriggerErrors(), $configuration->displayDetailsOnTestsThatTriggerNotices(), $configuration->displayDetailsOnTestsThatTriggerWarnings(), $configuration->reverseDefectList());
  91206. }
  91207. if ($configuration->outputIsTestDox()) {
  91208. self::$testDoxResultPrinter = new TestDoxResultPrinter(self::$printer, $configuration->colors());
  91209. }
  91210. if ($configuration->noOutput() || $configuration->noResults()) {
  91211. return;
  91212. }
  91213. if (self::$defaultResultPrinter !== null) {
  91214. return;
  91215. }
  91216. self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, $configuration->displayDetailsOnPhpunitDeprecations(), \true, \true, \true, $configuration->displayDetailsOnIncompleteTests(), $configuration->displayDetailsOnSkippedTests(), $configuration->displayDetailsOnTestsThatTriggerDeprecations(), $configuration->displayDetailsOnTestsThatTriggerErrors(), $configuration->displayDetailsOnTestsThatTriggerNotices(), $configuration->displayDetailsOnTestsThatTriggerWarnings(), $configuration->reverseDefectList());
  91217. }
  91218. private static function createSummaryPrinter(Configuration $configuration): void
  91219. {
  91220. assert(self::$printer !== null);
  91221. if (($configuration->noOutput() || $configuration->noResults()) && !($configuration->outputIsTeamCity() || $configuration->outputIsTestDox())) {
  91222. return;
  91223. }
  91224. self::$summaryPrinter = new \PHPUnit\TextUI\Output\SummaryPrinter(self::$printer, $configuration->colors());
  91225. }
  91226. /**
  91227. * @throws EventFacadeIsSealedException
  91228. * @throws UnknownSubscriberTypeException
  91229. */
  91230. private static function createUnexpectedOutputPrinter(): void
  91231. {
  91232. assert(self::$printer !== null);
  91233. new UnexpectedOutputPrinter(self::$printer, EventFacade::instance());
  91234. }
  91235. }
  91236. <?php
  91237. declare (strict_types=1);
  91238. /*
  91239. * This file is part of PHPUnit.
  91240. *
  91241. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91242. *
  91243. * For the full copyright and license information, please view the LICENSE
  91244. * file that was distributed with this source code.
  91245. */
  91246. namespace PHPUnit\TextUI\Output;
  91247. use function assert;
  91248. use function count;
  91249. use function dirname;
  91250. use function explode;
  91251. use function fclose;
  91252. use function fopen;
  91253. use function fsockopen;
  91254. use function fwrite;
  91255. use function str_replace;
  91256. use function str_starts_with;
  91257. use PHPUnit\Runner\DirectoryDoesNotExistException;
  91258. use PHPUnit\TextUI\CannotOpenSocketException;
  91259. use PHPUnit\TextUI\InvalidSocketException;
  91260. use PHPUnit\Util\Filesystem;
  91261. /**
  91262. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91263. *
  91264. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91265. */
  91266. final class DefaultPrinter implements \PHPUnit\TextUI\Output\Printer
  91267. {
  91268. /**
  91269. * @psalm-var closed-resource|resource
  91270. */
  91271. private $stream;
  91272. private readonly bool $isPhpStream;
  91273. private bool $isOpen;
  91274. /**
  91275. * @throws CannotOpenSocketException
  91276. * @throws DirectoryDoesNotExistException
  91277. * @throws InvalidSocketException
  91278. */
  91279. public static function from(string $out): self
  91280. {
  91281. return new self($out);
  91282. }
  91283. /**
  91284. * @throws CannotOpenSocketException
  91285. * @throws DirectoryDoesNotExistException
  91286. * @throws InvalidSocketException
  91287. */
  91288. public static function standardOutput(): self
  91289. {
  91290. return new self('php://stdout');
  91291. }
  91292. /**
  91293. * @throws CannotOpenSocketException
  91294. * @throws DirectoryDoesNotExistException
  91295. * @throws InvalidSocketException
  91296. */
  91297. public static function standardError(): self
  91298. {
  91299. return new self('php://stderr');
  91300. }
  91301. /**
  91302. * @throws CannotOpenSocketException
  91303. * @throws DirectoryDoesNotExistException
  91304. * @throws InvalidSocketException
  91305. */
  91306. private function __construct(string $out)
  91307. {
  91308. $this->isPhpStream = str_starts_with($out, 'php://');
  91309. if (str_starts_with($out, 'socket://')) {
  91310. $tmp = explode(':', str_replace('socket://', '', $out));
  91311. if (count($tmp) !== 2) {
  91312. throw new InvalidSocketException($out);
  91313. }
  91314. $stream = @fsockopen($tmp[0], (int) $tmp[1]);
  91315. if ($stream === \false) {
  91316. throw new CannotOpenSocketException($tmp[0], (int) $tmp[1]);
  91317. }
  91318. $this->stream = $stream;
  91319. $this->isOpen = \true;
  91320. return;
  91321. }
  91322. if (!$this->isPhpStream && !Filesystem::createDirectory(dirname($out))) {
  91323. throw new DirectoryDoesNotExistException(dirname($out));
  91324. }
  91325. $this->stream = fopen($out, 'wb');
  91326. $this->isOpen = \true;
  91327. }
  91328. public function print(string $buffer): void
  91329. {
  91330. assert($this->isOpen);
  91331. fwrite($this->stream, $buffer);
  91332. }
  91333. public function flush(): void
  91334. {
  91335. if ($this->isOpen && $this->isPhpStream) {
  91336. fclose($this->stream);
  91337. $this->isOpen = \false;
  91338. }
  91339. }
  91340. }
  91341. <?php
  91342. declare (strict_types=1);
  91343. /*
  91344. * This file is part of PHPUnit.
  91345. *
  91346. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91347. *
  91348. * For the full copyright and license information, please view the LICENSE
  91349. * file that was distributed with this source code.
  91350. */
  91351. namespace PHPUnit\TextUI\Output;
  91352. /**
  91353. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91354. *
  91355. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91356. */
  91357. final class NullPrinter implements \PHPUnit\TextUI\Output\Printer
  91358. {
  91359. public function print(string $buffer): void
  91360. {
  91361. }
  91362. public function flush(): void
  91363. {
  91364. }
  91365. }
  91366. <?php
  91367. declare (strict_types=1);
  91368. /*
  91369. * This file is part of PHPUnit.
  91370. *
  91371. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91372. *
  91373. * For the full copyright and license information, please view the LICENSE
  91374. * file that was distributed with this source code.
  91375. */
  91376. namespace PHPUnit\TextUI\Output;
  91377. /**
  91378. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91379. *
  91380. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  91381. */
  91382. interface Printer
  91383. {
  91384. public function print(string $buffer): void;
  91385. public function flush(): void;
  91386. }
  91387. <?php
  91388. declare (strict_types=1);
  91389. /*
  91390. * This file is part of PHPUnit.
  91391. *
  91392. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91393. *
  91394. * For the full copyright and license information, please view the LICENSE
  91395. * file that was distributed with this source code.
  91396. */
  91397. namespace PHPUnit\TextUI\Output;
  91398. use const PHP_EOL;
  91399. use function sprintf;
  91400. use PHPUnit\TestRunner\TestResult\TestResult;
  91401. use PHPUnit\Util\Color;
  91402. /**
  91403. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91404. *
  91405. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91406. */
  91407. final class SummaryPrinter
  91408. {
  91409. private readonly \PHPUnit\TextUI\Output\Printer $printer;
  91410. private readonly bool $colors;
  91411. private bool $countPrinted = \false;
  91412. public function __construct(\PHPUnit\TextUI\Output\Printer $printer, bool $colors)
  91413. {
  91414. $this->printer = $printer;
  91415. $this->colors = $colors;
  91416. }
  91417. public function print(TestResult $result): void
  91418. {
  91419. if ($result->numberOfTestsRun() === 0) {
  91420. $this->printWithColor('fg-black, bg-yellow', 'No tests executed!');
  91421. return;
  91422. }
  91423. if ($result->wasSuccessfulAndNoTestHasIssues() && !$result->hasTestSuiteSkippedEvents() && !$result->hasTestSkippedEvents()) {
  91424. $this->printWithColor('fg-black, bg-green', sprintf('OK (%d test%s, %d assertion%s)', $result->numberOfTestsRun(), $result->numberOfTestsRun() === 1 ? '' : 's', $result->numberOfAssertions(), $result->numberOfAssertions() === 1 ? '' : 's'));
  91425. $this->printNumberOfIssuesIgnoredByBaseline($result);
  91426. return;
  91427. }
  91428. $color = 'fg-black, bg-yellow';
  91429. if ($result->wasSuccessful()) {
  91430. if (!$result->hasTestsWithIssues()) {
  91431. $this->printWithColor($color, 'OK, but some tests were skipped!');
  91432. } else {
  91433. $this->printWithColor($color, 'OK, but there were issues!');
  91434. }
  91435. } else if ($result->hasTestErroredEvents() || $result->hasTestTriggeredPhpunitErrorEvents()) {
  91436. $color = 'fg-white, bg-red';
  91437. $this->printWithColor($color, 'ERRORS!');
  91438. } elseif ($result->hasTestFailedEvents()) {
  91439. $color = 'fg-white, bg-red';
  91440. $this->printWithColor($color, 'FAILURES!');
  91441. } elseif ($result->hasWarnings()) {
  91442. $this->printWithColor($color, 'WARNINGS!');
  91443. } elseif ($result->hasDeprecations()) {
  91444. $this->printWithColor($color, 'DEPRECATIONS!');
  91445. } elseif ($result->hasNotices()) {
  91446. $this->printWithColor($color, 'NOTICES!');
  91447. }
  91448. $this->printCountString($result->numberOfTestsRun(), 'Tests', $color, \true);
  91449. $this->printCountString($result->numberOfAssertions(), 'Assertions', $color, \true);
  91450. $this->printCountString($result->numberOfErrors(), 'Errors', $color);
  91451. $this->printCountString($result->numberOfTestFailedEvents(), 'Failures', $color);
  91452. $this->printCountString($result->numberOfWarnings(), 'Warnings', $color);
  91453. $this->printCountString($result->numberOfPhpOrUserDeprecations(), 'Deprecations', $color);
  91454. $this->printCountString($result->numberOfPhpunitDeprecations(), 'PHPUnit Deprecations', $color);
  91455. $this->printCountString($result->numberOfNotices(), 'Notices', $color);
  91456. $this->printCountString($result->numberOfTestSuiteSkippedEvents() + $result->numberOfTestSkippedEvents(), 'Skipped', $color);
  91457. $this->printCountString($result->numberOfTestMarkedIncompleteEvents(), 'Incomplete', $color);
  91458. $this->printCountString($result->numberOfTestsWithTestConsideredRiskyEvents(), 'Risky', $color);
  91459. $this->printWithColor($color, '.');
  91460. $this->printNumberOfIssuesIgnoredByBaseline($result);
  91461. }
  91462. private function printCountString(int $count, string $name, string $color, bool $always = \false): void
  91463. {
  91464. if ($always || $count > 0) {
  91465. $this->printWithColor($color, sprintf('%s%s: %d', $this->countPrinted ? ', ' : '', $name, $count), \false);
  91466. $this->countPrinted = \true;
  91467. }
  91468. }
  91469. private function printWithColor(string $color, string $buffer, bool $lf = \true): void
  91470. {
  91471. if ($this->colors) {
  91472. $buffer = Color::colorizeTextBox($color, $buffer);
  91473. }
  91474. $this->printer->print($buffer);
  91475. if ($lf) {
  91476. $this->printer->print(PHP_EOL);
  91477. }
  91478. }
  91479. private function printNumberOfIssuesIgnoredByBaseline(TestResult $result): void
  91480. {
  91481. if ($result->hasIssuesIgnoredByBaseline()) {
  91482. $this->printer->print(sprintf('%s%d issue%s %s ignored by baseline.%s', PHP_EOL, $result->numberOfIssuesIgnoredByBaseline(), $result->numberOfIssuesIgnoredByBaseline() > 1 ? 's' : '', $result->numberOfIssuesIgnoredByBaseline() > 1 ? 'were' : 'was', PHP_EOL));
  91483. }
  91484. }
  91485. }
  91486. <?php
  91487. declare (strict_types=1);
  91488. /*
  91489. * This file is part of PHPUnit.
  91490. *
  91491. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91492. *
  91493. * For the full copyright and license information, please view the LICENSE
  91494. * file that was distributed with this source code.
  91495. */
  91496. namespace PHPUnit\TextUI\Output\TestDox;
  91497. use const PHP_EOL;
  91498. use function array_map;
  91499. use function assert;
  91500. use function explode;
  91501. use function implode;
  91502. use function preg_match;
  91503. use function preg_split;
  91504. use function rtrim;
  91505. use function str_starts_with;
  91506. use function trim;
  91507. use PHPUnit\Event\Code\Throwable;
  91508. use PHPUnit\Framework\TestStatus\TestStatus;
  91509. use PHPUnit\Logging\TestDox\TestResult as TestDoxTestResult;
  91510. use PHPUnit\Logging\TestDox\TestResultCollection;
  91511. use PHPUnit\TextUI\Output\Printer;
  91512. use PHPUnit\Util\Color;
  91513. /**
  91514. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91515. *
  91516. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91517. */
  91518. final class ResultPrinter
  91519. {
  91520. private readonly Printer $printer;
  91521. private readonly bool $colors;
  91522. public function __construct(Printer $printer, bool $colors)
  91523. {
  91524. $this->printer = $printer;
  91525. $this->colors = $colors;
  91526. }
  91527. /**
  91528. * @psalm-param array<string, TestResultCollection> $tests
  91529. */
  91530. public function print(array $tests): void
  91531. {
  91532. foreach ($tests as $prettifiedClassName => $_tests) {
  91533. $this->printPrettifiedClassName($prettifiedClassName);
  91534. foreach ($_tests as $test) {
  91535. $this->printTestResult($test);
  91536. }
  91537. $this->printer->print(PHP_EOL);
  91538. }
  91539. }
  91540. /**
  91541. * @psalm-param string $prettifiedClassName
  91542. */
  91543. private function printPrettifiedClassName(string $prettifiedClassName): void
  91544. {
  91545. $buffer = $prettifiedClassName;
  91546. if ($this->colors) {
  91547. $buffer = Color::colorizeTextBox('underlined', $buffer);
  91548. }
  91549. $this->printer->print($buffer . PHP_EOL);
  91550. }
  91551. private function printTestResult(TestDoxTestResult $test): void
  91552. {
  91553. $this->printTestResultHeader($test);
  91554. $this->printTestResultBody($test);
  91555. }
  91556. private function printTestResultHeader(TestDoxTestResult $test): void
  91557. {
  91558. $buffer = ' ' . $this->symbolFor($test->status()) . ' ';
  91559. if ($this->colors) {
  91560. $this->printer->print(Color::colorizeTextBox($this->colorFor($test->status()), $buffer));
  91561. } else {
  91562. $this->printer->print($buffer);
  91563. }
  91564. $this->printer->print($test->test()->testDox()->prettifiedMethodName($this->colors) . PHP_EOL);
  91565. }
  91566. private function printTestResultBody(TestDoxTestResult $test): void
  91567. {
  91568. if ($test->status()->isSuccess()) {
  91569. return;
  91570. }
  91571. if (!$test->hasThrowable()) {
  91572. return;
  91573. }
  91574. $this->printTestResultBodyStart($test);
  91575. $this->printThrowable($test);
  91576. $this->printTestResultBodyEnd($test);
  91577. }
  91578. private function printTestResultBodyStart(TestDoxTestResult $test): void
  91579. {
  91580. $this->printer->print($this->prefixLines($this->prefixFor('start', $test->status()), ''));
  91581. $this->printer->print(PHP_EOL);
  91582. }
  91583. private function printTestResultBodyEnd(TestDoxTestResult $test): void
  91584. {
  91585. $this->printer->print(PHP_EOL);
  91586. $this->printer->print($this->prefixLines($this->prefixFor('last', $test->status()), ''));
  91587. $this->printer->print(PHP_EOL);
  91588. }
  91589. private function printThrowable(TestDoxTestResult $test): void
  91590. {
  91591. $throwable = $test->throwable();
  91592. assert($throwable instanceof Throwable);
  91593. $message = trim($throwable->description());
  91594. $stackTrace = $this->formatStackTrace($throwable->stackTrace());
  91595. $diff = '';
  91596. if (!empty($message) && $this->colors) {
  91597. ['message' => $message, 'diff' => $diff] = $this->colorizeMessageAndDiff($message, $this->messageColorFor($test->status()));
  91598. }
  91599. if (!empty($message)) {
  91600. $this->printer->print($this->prefixLines($this->prefixFor('message', $test->status()), $message));
  91601. $this->printer->print(PHP_EOL);
  91602. }
  91603. if (!empty($diff)) {
  91604. $this->printer->print($this->prefixLines($this->prefixFor('diff', $test->status()), $diff));
  91605. $this->printer->print(PHP_EOL);
  91606. }
  91607. if (!empty($stackTrace)) {
  91608. if (!empty($message) || !empty($diff)) {
  91609. $prefix = $this->prefixFor('default', $test->status());
  91610. } else {
  91611. $prefix = $this->prefixFor('trace', $test->status());
  91612. }
  91613. $this->printer->print($this->prefixLines($prefix, PHP_EOL . $stackTrace));
  91614. }
  91615. }
  91616. /**
  91617. * @psalm-return array{message: string, diff: string}
  91618. */
  91619. private function colorizeMessageAndDiff(string $buffer, string $style): array
  91620. {
  91621. $lines = $buffer ? array_map('\rtrim', explode(PHP_EOL, $buffer)) : [];
  91622. $message = [];
  91623. $diff = [];
  91624. $insideDiff = \false;
  91625. foreach ($lines as $line) {
  91626. if ($line === '--- Expected') {
  91627. $insideDiff = \true;
  91628. }
  91629. if (!$insideDiff) {
  91630. $message[] = $line;
  91631. } else {
  91632. if (str_starts_with($line, '-')) {
  91633. $line = Color::colorize('fg-red', Color::visualizeWhitespace($line, \true));
  91634. } elseif (str_starts_with($line, '+')) {
  91635. $line = Color::colorize('fg-green', Color::visualizeWhitespace($line, \true));
  91636. } elseif ($line === '@@ @@') {
  91637. $line = Color::colorize('fg-cyan', $line);
  91638. }
  91639. $diff[] = $line;
  91640. }
  91641. }
  91642. $message = implode(PHP_EOL, $message);
  91643. $diff = implode(PHP_EOL, $diff);
  91644. if (!empty($message)) {
  91645. $message = Color::colorizeTextBox($style, $message);
  91646. }
  91647. return ['message' => $message, 'diff' => $diff];
  91648. }
  91649. private function formatStackTrace(string $stackTrace): string
  91650. {
  91651. if (!$this->colors) {
  91652. return rtrim($stackTrace);
  91653. }
  91654. $lines = [];
  91655. $previousPath = '';
  91656. foreach (explode(PHP_EOL, $stackTrace) as $line) {
  91657. if (preg_match('/^(.*):(\d+)$/', $line, $matches)) {
  91658. $lines[] = Color::colorizePath($matches[1], $previousPath) . Color::dim(':') . Color::colorize('fg-blue', $matches[2]) . "\n";
  91659. $previousPath = $matches[1];
  91660. continue;
  91661. }
  91662. $lines[] = $line;
  91663. $previousPath = '';
  91664. }
  91665. return rtrim(implode('', $lines));
  91666. }
  91667. private function prefixLines(string $prefix, string $message): string
  91668. {
  91669. return implode(PHP_EOL, array_map(static fn(string $line) => ' ' . $prefix . ($line ? ' ' . $line : ''), preg_split('/\r\n|\r|\n/', $message)));
  91670. }
  91671. /**
  91672. * @psalm-param 'default'|'start'|'message'|'diff'|'trace'|'last' $type
  91673. */
  91674. private function prefixFor(string $type, TestStatus $status): string
  91675. {
  91676. if (!$this->colors) {
  91677. return '│';
  91678. }
  91679. return Color::colorize($this->colorFor($status), match ($type) {
  91680. 'default' => '│',
  91681. 'start' => '�',
  91682. 'message' => '├',
  91683. 'diff' => '┊',
  91684. 'trace' => '╵',
  91685. 'last' => 'â”´',
  91686. });
  91687. }
  91688. private function colorFor(TestStatus $status): string
  91689. {
  91690. if ($status->isSuccess()) {
  91691. return 'fg-green';
  91692. }
  91693. if ($status->isError()) {
  91694. return 'fg-yellow';
  91695. }
  91696. if ($status->isFailure()) {
  91697. return 'fg-red';
  91698. }
  91699. if ($status->isSkipped()) {
  91700. return 'fg-cyan';
  91701. }
  91702. if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
  91703. return 'fg-yellow';
  91704. }
  91705. return 'fg-blue';
  91706. }
  91707. private function messageColorFor(TestStatus $status): string
  91708. {
  91709. if ($status->isSuccess()) {
  91710. return '';
  91711. }
  91712. if ($status->isError()) {
  91713. return 'bg-yellow,fg-black';
  91714. }
  91715. if ($status->isFailure()) {
  91716. return 'bg-red,fg-white';
  91717. }
  91718. if ($status->isSkipped()) {
  91719. return 'fg-cyan';
  91720. }
  91721. if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
  91722. return 'fg-yellow';
  91723. }
  91724. return 'fg-white,bg-blue';
  91725. }
  91726. private function symbolFor(TestStatus $status): string
  91727. {
  91728. if ($status->isSuccess()) {
  91729. return '✔';
  91730. }
  91731. if ($status->isError() || $status->isFailure()) {
  91732. return '✘';
  91733. }
  91734. if ($status->isSkipped()) {
  91735. return '↩';
  91736. }
  91737. if ($status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
  91738. return 'âš ';
  91739. }
  91740. if ($status->isIncomplete()) {
  91741. return '∅';
  91742. }
  91743. return '?';
  91744. }
  91745. }
  91746. <?php
  91747. declare (strict_types=1);
  91748. /*
  91749. * This file is part of PHPUnit.
  91750. *
  91751. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91752. *
  91753. * For the full copyright and license information, please view the LICENSE
  91754. * file that was distributed with this source code.
  91755. */
  91756. namespace PHPUnit\TextUI;
  91757. use PHPUnit\TestRunner\TestResult\TestResult;
  91758. /**
  91759. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91760. *
  91761. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91762. */
  91763. final class ShellExitCodeCalculator
  91764. {
  91765. private const SUCCESS_EXIT = 0;
  91766. private const FAILURE_EXIT = 1;
  91767. private const EXCEPTION_EXIT = 2;
  91768. public function calculate(bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, TestResult $result): int
  91769. {
  91770. $returnCode = self::FAILURE_EXIT;
  91771. if ($result->wasSuccessful()) {
  91772. $returnCode = self::SUCCESS_EXIT;
  91773. }
  91774. if ($failOnEmptyTestSuite && !$result->hasTests()) {
  91775. $returnCode = self::FAILURE_EXIT;
  91776. }
  91777. if ($result->wasSuccessfulIgnoringPhpunitWarnings()) {
  91778. if ($failOnDeprecation && $result->hasPhpOrUserDeprecations()) {
  91779. $returnCode = self::FAILURE_EXIT;
  91780. }
  91781. if ($failOnPhpunitDeprecation && $result->hasPhpunitDeprecations()) {
  91782. $returnCode = self::FAILURE_EXIT;
  91783. }
  91784. if ($failOnIncomplete && $result->hasIncompleteTests()) {
  91785. $returnCode = self::FAILURE_EXIT;
  91786. }
  91787. if ($failOnNotice && $result->hasNotices()) {
  91788. $returnCode = self::FAILURE_EXIT;
  91789. }
  91790. if ($failOnRisky && $result->hasRiskyTests()) {
  91791. $returnCode = self::FAILURE_EXIT;
  91792. }
  91793. if ($failOnSkipped && $result->hasSkippedTests()) {
  91794. $returnCode = self::FAILURE_EXIT;
  91795. }
  91796. if ($failOnWarning && $result->hasWarnings()) {
  91797. $returnCode = self::FAILURE_EXIT;
  91798. }
  91799. }
  91800. if ($result->hasErrors()) {
  91801. $returnCode = self::EXCEPTION_EXIT;
  91802. }
  91803. return $returnCode;
  91804. }
  91805. }
  91806. <?php
  91807. declare (strict_types=1);
  91808. /*
  91809. * This file is part of PHPUnit.
  91810. *
  91811. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91812. *
  91813. * For the full copyright and license information, please view the LICENSE
  91814. * file that was distributed with this source code.
  91815. */
  91816. namespace PHPUnit\TextUI;
  91817. use function mt_srand;
  91818. use PHPUnit\Event;
  91819. use PHPUnit\Framework\TestSuite;
  91820. use PHPUnit\Runner\ResultCache\ResultCache;
  91821. use PHPUnit\Runner\TestSuiteSorter;
  91822. use PHPUnit\TextUI\Configuration\Configuration;
  91823. use Throwable;
  91824. /**
  91825. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91826. *
  91827. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91828. */
  91829. final class TestRunner
  91830. {
  91831. /**
  91832. * @throws RuntimeException
  91833. */
  91834. public function run(Configuration $configuration, ResultCache $resultCache, TestSuite $suite): void
  91835. {
  91836. try {
  91837. Event\Facade::emitter()->testRunnerStarted();
  91838. if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) {
  91839. mt_srand($configuration->randomOrderSeed());
  91840. }
  91841. if ($configuration->executionOrder() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->executionOrderDefects() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->resolveDependencies()) {
  91842. $resultCache->load();
  91843. (new TestSuiteSorter($resultCache))->reorderTestsInSuite($suite, $configuration->executionOrder(), $configuration->resolveDependencies(), $configuration->executionOrderDefects());
  91844. Event\Facade::emitter()->testSuiteSorted($configuration->executionOrder(), $configuration->executionOrderDefects(), $configuration->resolveDependencies());
  91845. }
  91846. (new \PHPUnit\TextUI\TestSuiteFilterProcessor())->process($configuration, $suite);
  91847. Event\Facade::emitter()->testRunnerExecutionStarted(Event\TestSuite\TestSuiteBuilder::from($suite));
  91848. $suite->run();
  91849. Event\Facade::emitter()->testRunnerExecutionFinished();
  91850. Event\Facade::emitter()->testRunnerFinished();
  91851. } catch (Throwable $t) {
  91852. throw new \PHPUnit\TextUI\RuntimeException($t->getMessage(), (int) $t->getCode(), $t);
  91853. }
  91854. }
  91855. }
  91856. <?php
  91857. declare (strict_types=1);
  91858. /*
  91859. * This file is part of PHPUnit.
  91860. *
  91861. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91862. *
  91863. * For the full copyright and license information, please view the LICENSE
  91864. * file that was distributed with this source code.
  91865. */
  91866. namespace PHPUnit\TextUI;
  91867. use function array_map;
  91868. use PHPUnit\Event;
  91869. use PHPUnit\Framework\TestSuite;
  91870. use PHPUnit\Runner\Filter\Factory;
  91871. use PHPUnit\TextUI\Configuration\Configuration;
  91872. use PHPUnit\TextUI\Configuration\FilterNotConfiguredException;
  91873. /**
  91874. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91875. *
  91876. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91877. */
  91878. final class TestSuiteFilterProcessor
  91879. {
  91880. /**
  91881. * @throws Event\RuntimeException
  91882. * @throws FilterNotConfiguredException
  91883. */
  91884. public function process(Configuration $configuration, TestSuite $suite): void
  91885. {
  91886. $factory = new Factory();
  91887. if (!$configuration->hasFilter() && !$configuration->hasGroups() && !$configuration->hasExcludeGroups() && !$configuration->hasTestsCovering() && !$configuration->hasTestsUsing()) {
  91888. return;
  91889. }
  91890. if ($configuration->hasExcludeGroups()) {
  91891. $factory->addExcludeGroupFilter($configuration->excludeGroups());
  91892. }
  91893. if ($configuration->hasGroups()) {
  91894. $factory->addIncludeGroupFilter($configuration->groups());
  91895. }
  91896. if ($configuration->hasTestsCovering()) {
  91897. $factory->addIncludeGroupFilter(array_map(static fn(string $name): string => '__phpunit_covers_' . $name, $configuration->testsCovering()));
  91898. }
  91899. if ($configuration->hasTestsUsing()) {
  91900. $factory->addIncludeGroupFilter(array_map(static fn(string $name): string => '__phpunit_uses_' . $name, $configuration->testsUsing()));
  91901. }
  91902. if ($configuration->hasFilter()) {
  91903. $factory->addNameFilter($configuration->filter());
  91904. }
  91905. $suite->injectFilter($factory);
  91906. Event\Facade::emitter()->testSuiteFiltered(Event\TestSuite\TestSuiteBuilder::from($suite));
  91907. }
  91908. }
  91909. <?php
  91910. declare (strict_types=1);
  91911. /*
  91912. * This file is part of PHPUnit.
  91913. *
  91914. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91915. *
  91916. * For the full copyright and license information, please view the LICENSE
  91917. * file that was distributed with this source code.
  91918. */
  91919. namespace PHPUnit\Util;
  91920. use Throwable;
  91921. /**
  91922. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91923. *
  91924. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91925. */
  91926. final class Cloner
  91927. {
  91928. /**
  91929. * @psalm-template OriginalType of object
  91930. *
  91931. * @psalm-param OriginalType $original
  91932. *
  91933. * @psalm-return OriginalType
  91934. */
  91935. public static function clone(object $original): object
  91936. {
  91937. try {
  91938. return clone $original;
  91939. } catch (Throwable) {
  91940. return $original;
  91941. }
  91942. }
  91943. }
  91944. <?php
  91945. declare (strict_types=1);
  91946. /*
  91947. * This file is part of PHPUnit.
  91948. *
  91949. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  91950. *
  91951. * For the full copyright and license information, please view the LICENSE
  91952. * file that was distributed with this source code.
  91953. */
  91954. namespace PHPUnit\Util;
  91955. use const DIRECTORY_SEPARATOR;
  91956. use const PHP_EOL;
  91957. use function array_map;
  91958. use function count;
  91959. use function explode;
  91960. use function implode;
  91961. use function max;
  91962. use function min;
  91963. use function preg_replace;
  91964. use function preg_replace_callback;
  91965. use function preg_split;
  91966. use function sprintf;
  91967. use function str_pad;
  91968. use function strtr;
  91969. use function trim;
  91970. /**
  91971. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  91972. *
  91973. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  91974. */
  91975. final class Color
  91976. {
  91977. /**
  91978. * @psalm-var array<string,string>
  91979. */
  91980. private const WHITESPACE_MAP = [' ' => '·', "\t" => '⇥'];
  91981. /**
  91982. * @psalm-var array<string,string>
  91983. */
  91984. private const WHITESPACE_EOL_MAP = [' ' => '·', "\t" => '⇥', "\n" => '↵', "\r" => '⟵'];
  91985. /**
  91986. * @psalm-var array<string,string>
  91987. */
  91988. private static array $ansiCodes = ['reset' => '0', 'bold' => '1', 'dim' => '2', 'dim-reset' => '22', 'underlined' => '4', 'fg-default' => '39', 'fg-black' => '30', 'fg-red' => '31', 'fg-green' => '32', 'fg-yellow' => '33', 'fg-blue' => '34', 'fg-magenta' => '35', 'fg-cyan' => '36', 'fg-white' => '37', 'bg-default' => '49', 'bg-black' => '40', 'bg-red' => '41', 'bg-green' => '42', 'bg-yellow' => '43', 'bg-blue' => '44', 'bg-magenta' => '45', 'bg-cyan' => '46', 'bg-white' => '47'];
  91989. public static function colorize(string $color, string $buffer): string
  91990. {
  91991. if (trim($buffer) === '') {
  91992. return $buffer;
  91993. }
  91994. $codes = array_map('\trim', explode(',', $color));
  91995. $styles = [];
  91996. foreach ($codes as $code) {
  91997. if (isset(self::$ansiCodes[$code])) {
  91998. $styles[] = self::$ansiCodes[$code] ?? '';
  91999. }
  92000. }
  92001. if (empty($styles)) {
  92002. return $buffer;
  92003. }
  92004. return self::optimizeColor(sprintf("\x1b[%sm", implode(';', $styles)) . $buffer . "\x1b[0m");
  92005. }
  92006. public static function colorizeTextBox(string $color, string $buffer): string
  92007. {
  92008. $lines = preg_split('/\r\n|\r|\n/', $buffer);
  92009. $padding = max(array_map('\strlen', $lines));
  92010. $styledLines = [];
  92011. foreach ($lines as $line) {
  92012. $styledLines[] = self::colorize($color, str_pad($line, $padding));
  92013. }
  92014. return implode(PHP_EOL, $styledLines);
  92015. }
  92016. public static function colorizePath(string $path, ?string $previousPath = null, bool $colorizeFilename = \false): string
  92017. {
  92018. if ($previousPath === null) {
  92019. $previousPath = '';
  92020. }
  92021. $path = explode(DIRECTORY_SEPARATOR, $path);
  92022. $previousPath = explode(DIRECTORY_SEPARATOR, $previousPath);
  92023. for ($i = 0; $i < min(count($path), count($previousPath)); $i++) {
  92024. if ($path[$i] === $previousPath[$i]) {
  92025. $path[$i] = self::dim($path[$i]);
  92026. }
  92027. }
  92028. if ($colorizeFilename) {
  92029. $last = count($path) - 1;
  92030. $path[$last] = preg_replace_callback('/([\-_.]+|phpt$)/', static fn($matches) => self::dim($matches[0]), $path[$last]);
  92031. }
  92032. return self::optimizeColor(implode(self::dim(DIRECTORY_SEPARATOR), $path));
  92033. }
  92034. public static function dim(string $buffer): string
  92035. {
  92036. if (trim($buffer) === '') {
  92037. return $buffer;
  92038. }
  92039. return "\x1b[2m{$buffer}\x1b[22m";
  92040. }
  92041. public static function visualizeWhitespace(string $buffer, bool $visualizeEOL = \false): string
  92042. {
  92043. $replaceMap = $visualizeEOL ? self::WHITESPACE_EOL_MAP : self::WHITESPACE_MAP;
  92044. return preg_replace_callback('/\s+/', static fn($matches) => self::dim(strtr($matches[0], $replaceMap)), $buffer);
  92045. }
  92046. private static function optimizeColor(string $buffer): string
  92047. {
  92048. return preg_replace(["/\x1b\\[22m\x1b\\[2m/", "/\x1b\\[([^m]*)m\x1b\\[([1-9][0-9;]*)m/", "/(\x1b\\[[^m]*m)+(\x1b\\[0m)/"], ['', "\x1b[\$1;\$2m", '$2'], $buffer);
  92049. }
  92050. }
  92051. <?php
  92052. declare (strict_types=1);
  92053. /*
  92054. * This file is part of PHPUnit.
  92055. *
  92056. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92057. *
  92058. * For the full copyright and license information, please view the LICENSE
  92059. * file that was distributed with this source code.
  92060. */
  92061. namespace PHPUnit\Util;
  92062. use Throwable;
  92063. /**
  92064. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92065. *
  92066. * @internal This interface is not covered by the backward compatibility promise for PHPUnit
  92067. */
  92068. interface Exception extends Throwable
  92069. {
  92070. }
  92071. <?php
  92072. declare (strict_types=1);
  92073. /*
  92074. * This file is part of PHPUnit.
  92075. *
  92076. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92077. *
  92078. * For the full copyright and license information, please view the LICENSE
  92079. * file that was distributed with this source code.
  92080. */
  92081. namespace PHPUnit\Util;
  92082. use function sprintf;
  92083. use RuntimeException;
  92084. /**
  92085. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92086. *
  92087. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92088. */
  92089. final class InvalidDirectoryException extends RuntimeException implements \PHPUnit\Util\Exception
  92090. {
  92091. public function __construct(string $directory)
  92092. {
  92093. parent::__construct(sprintf('"%s" is not a directory', $directory));
  92094. }
  92095. }
  92096. <?php
  92097. declare (strict_types=1);
  92098. /*
  92099. * This file is part of PHPUnit.
  92100. *
  92101. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92102. *
  92103. * For the full copyright and license information, please view the LICENSE
  92104. * file that was distributed with this source code.
  92105. */
  92106. namespace PHPUnit\Util;
  92107. use RuntimeException;
  92108. /**
  92109. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92110. *
  92111. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92112. */
  92113. final class InvalidJsonException extends RuntimeException implements \PHPUnit\Util\Exception
  92114. {
  92115. }
  92116. <?php
  92117. declare (strict_types=1);
  92118. /*
  92119. * This file is part of PHPUnit.
  92120. *
  92121. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92122. *
  92123. * For the full copyright and license information, please view the LICENSE
  92124. * file that was distributed with this source code.
  92125. */
  92126. namespace PHPUnit\Util;
  92127. use function sprintf;
  92128. use RuntimeException;
  92129. /**
  92130. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92131. *
  92132. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92133. */
  92134. final class InvalidVersionOperatorException extends RuntimeException implements \PHPUnit\Util\Exception
  92135. {
  92136. public function __construct(string $operator)
  92137. {
  92138. parent::__construct(sprintf('"%s" is not a valid version_compare() operator', $operator));
  92139. }
  92140. }
  92141. <?php
  92142. declare (strict_types=1);
  92143. /*
  92144. * This file is part of PHPUnit.
  92145. *
  92146. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92147. *
  92148. * For the full copyright and license information, please view the LICENSE
  92149. * file that was distributed with this source code.
  92150. */
  92151. namespace PHPUnit\Util\PHP;
  92152. use PHPUnit\Util\Exception;
  92153. use RuntimeException;
  92154. /**
  92155. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92156. *
  92157. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92158. */
  92159. final class PhpProcessException extends RuntimeException implements Exception
  92160. {
  92161. }
  92162. <?php
  92163. declare (strict_types=1);
  92164. /*
  92165. * This file is part of PHPUnit.
  92166. *
  92167. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92168. *
  92169. * For the full copyright and license information, please view the LICENSE
  92170. * file that was distributed with this source code.
  92171. */
  92172. namespace PHPUnit\Util\Xml;
  92173. use PHPUnit\Util\Exception;
  92174. use RuntimeException;
  92175. /**
  92176. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92177. *
  92178. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92179. */
  92180. final class XmlException extends RuntimeException implements Exception
  92181. {
  92182. }
  92183. <?php
  92184. declare (strict_types=1);
  92185. /*
  92186. * This file is part of PHPUnit.
  92187. *
  92188. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92189. *
  92190. * For the full copyright and license information, please view the LICENSE
  92191. * file that was distributed with this source code.
  92192. */
  92193. namespace PHPUnit\Util;
  92194. use const PHP_OS_FAMILY;
  92195. use function class_exists;
  92196. use function defined;
  92197. use function dirname;
  92198. use function is_dir;
  92199. use function realpath;
  92200. use function str_starts_with;
  92201. use function sys_get_temp_dir;
  92202. use PHPUnitPHAR\Composer\Autoload\ClassLoader;
  92203. use PHPUnitPHAR\DeepCopy\DeepCopy;
  92204. use PHPUnitPHAR\PharIo\Manifest\Manifest;
  92205. use PHPUnitPHAR\PharIo\Version\Version as PharIoVersion;
  92206. use PHPUnitPHAR\PhpParser\Parser;
  92207. use PHPUnit\Framework\TestCase;
  92208. use ReflectionClass;
  92209. use PHPUnitPHAR\SebastianBergmann\CliParser\Parser as CliParser;
  92210. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  92211. use PHPUnitPHAR\SebastianBergmann\CodeUnit\CodeUnit;
  92212. use PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup\Wizard;
  92213. use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
  92214. use PHPUnitPHAR\SebastianBergmann\Complexity\Calculator;
  92215. use PHPUnitPHAR\SebastianBergmann\Diff\Diff;
  92216. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  92217. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  92218. use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
  92219. use PHPUnitPHAR\SebastianBergmann\GlobalState\Snapshot;
  92220. use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
  92221. use PHPUnitPHAR\SebastianBergmann\LinesOfCode\Counter;
  92222. use PHPUnitPHAR\SebastianBergmann\ObjectEnumerator\Enumerator;
  92223. use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
  92224. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  92225. use PHPUnitPHAR\SebastianBergmann\Template\Template;
  92226. use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
  92227. use PHPUnitPHAR\SebastianBergmann\Type\TypeName;
  92228. use PHPUnitPHAR\SebastianBergmann\Version;
  92229. use PHPUnitPHAR\TheSeer\Tokenizer\Tokenizer;
  92230. /**
  92231. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92232. */
  92233. final class ExcludeList
  92234. {
  92235. /**
  92236. * @psalm-var array<string,int>
  92237. */
  92238. private const EXCLUDED_CLASS_NAMES = [
  92239. // composer
  92240. ClassLoader::class => 1,
  92241. // myclabs/deepcopy
  92242. DeepCopy::class => 1,
  92243. // nikic/php-parser
  92244. Parser::class => 1,
  92245. // phar-io/manifest
  92246. Manifest::class => 1,
  92247. // phar-io/version
  92248. PharIoVersion::class => 1,
  92249. // phpunit/phpunit
  92250. TestCase::class => 2,
  92251. // phpunit/php-code-coverage
  92252. CodeCoverage::class => 1,
  92253. // phpunit/php-file-iterator
  92254. FileIteratorFacade::class => 1,
  92255. // phpunit/php-invoker
  92256. Invoker::class => 1,
  92257. // phpunit/php-text-template
  92258. Template::class => 1,
  92259. // phpunit/php-timer
  92260. Timer::class => 1,
  92261. // sebastian/cli-parser
  92262. CliParser::class => 1,
  92263. // sebastian/code-unit
  92264. CodeUnit::class => 1,
  92265. // sebastian/code-unit-reverse-lookup
  92266. Wizard::class => 1,
  92267. // sebastian/comparator
  92268. Comparator::class => 1,
  92269. // sebastian/complexity
  92270. Calculator::class => 1,
  92271. // sebastian/diff
  92272. Diff::class => 1,
  92273. // sebastian/environment
  92274. Runtime::class => 1,
  92275. // sebastian/exporter
  92276. Exporter::class => 1,
  92277. // sebastian/global-state
  92278. Snapshot::class => 1,
  92279. // sebastian/lines-of-code
  92280. Counter::class => 1,
  92281. // sebastian/object-enumerator
  92282. Enumerator::class => 1,
  92283. // sebastian/object-reflector
  92284. ObjectReflector::class => 1,
  92285. // sebastian/recursion-context
  92286. Context::class => 1,
  92287. // sebastian/type
  92288. TypeName::class => 1,
  92289. // sebastian/version
  92290. Version::class => 1,
  92291. // theseer/tokenizer
  92292. Tokenizer::class => 1,
  92293. ];
  92294. /**
  92295. * @psalm-var list<string>
  92296. */
  92297. private static array $directories = [];
  92298. private static bool $initialized = \false;
  92299. private readonly bool $enabled;
  92300. /**
  92301. * @psalm-param non-empty-string $directory
  92302. *
  92303. * @throws InvalidDirectoryException
  92304. */
  92305. public static function addDirectory(string $directory): void
  92306. {
  92307. if (!is_dir($directory)) {
  92308. throw new \PHPUnit\Util\InvalidDirectoryException($directory);
  92309. }
  92310. self::$directories[] = realpath($directory);
  92311. }
  92312. public function __construct(?bool $enabled = null)
  92313. {
  92314. if ($enabled === null) {
  92315. $enabled = !defined('PHPUNIT_TESTSUITE');
  92316. }
  92317. $this->enabled = $enabled;
  92318. }
  92319. /**
  92320. * @psalm-return list<string>
  92321. */
  92322. public function getExcludedDirectories(): array
  92323. {
  92324. self::initialize();
  92325. return self::$directories;
  92326. }
  92327. public function isExcluded(string $file): bool
  92328. {
  92329. if (!$this->enabled) {
  92330. return \false;
  92331. }
  92332. self::initialize();
  92333. foreach (self::$directories as $directory) {
  92334. if (str_starts_with($file, $directory)) {
  92335. return \true;
  92336. }
  92337. }
  92338. return \false;
  92339. }
  92340. private static function initialize(): void
  92341. {
  92342. if (self::$initialized) {
  92343. return;
  92344. }
  92345. foreach (self::EXCLUDED_CLASS_NAMES as $className => $parent) {
  92346. if (!class_exists($className)) {
  92347. continue;
  92348. }
  92349. $directory = (new ReflectionClass($className))->getFileName();
  92350. for ($i = 0; $i < $parent; $i++) {
  92351. $directory = dirname($directory);
  92352. }
  92353. self::$directories[] = $directory;
  92354. }
  92355. /**
  92356. * Hide process isolation workaround on Windows:
  92357. * tempnam() prefix is limited to first 3 characters.
  92358. *
  92359. * @see https://php.net/manual/en/function.tempnam.php
  92360. */
  92361. if (PHP_OS_FAMILY === 'Windows') {
  92362. // @codeCoverageIgnoreStart
  92363. self::$directories[] = sys_get_temp_dir() . '\PHP';
  92364. // @codeCoverageIgnoreEnd
  92365. }
  92366. self::$initialized = \true;
  92367. }
  92368. }
  92369. <?php
  92370. declare (strict_types=1);
  92371. /*
  92372. * This file is part of PHPUnit.
  92373. *
  92374. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92375. *
  92376. * For the full copyright and license information, please view the LICENSE
  92377. * file that was distributed with this source code.
  92378. */
  92379. namespace PHPUnit\Util;
  92380. use function is_array;
  92381. use function is_scalar;
  92382. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  92383. /**
  92384. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92385. *
  92386. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92387. *
  92388. * @deprecated
  92389. */
  92390. final class Exporter
  92391. {
  92392. public static function export(mixed $value, bool $exportObjects = \false): string
  92393. {
  92394. if (self::isExportable($value) || $exportObjects) {
  92395. return (new \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter())->export($value);
  92396. }
  92397. return '{enable export of objects to see this value}';
  92398. }
  92399. private static function isExportable(mixed &$value, ?Context $context = null): bool
  92400. {
  92401. if (is_scalar($value) || $value === null) {
  92402. return \true;
  92403. }
  92404. if (!is_array($value)) {
  92405. return \false;
  92406. }
  92407. if (!$context) {
  92408. $context = new Context();
  92409. }
  92410. if ($context->contains($value) !== \false) {
  92411. return \true;
  92412. }
  92413. $array = $value;
  92414. $context->add($value);
  92415. foreach ($array as &$_value) {
  92416. if (!self::isExportable($_value, $context)) {
  92417. return \false;
  92418. }
  92419. }
  92420. return \true;
  92421. }
  92422. }
  92423. <?php
  92424. declare (strict_types=1);
  92425. /*
  92426. * This file is part of PHPUnit.
  92427. *
  92428. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92429. *
  92430. * For the full copyright and license information, please view the LICENSE
  92431. * file that was distributed with this source code.
  92432. */
  92433. namespace PHPUnit\Util;
  92434. use const DIRECTORY_SEPARATOR;
  92435. use function basename;
  92436. use function dirname;
  92437. use function is_dir;
  92438. use function mkdir;
  92439. use function realpath;
  92440. use function str_starts_with;
  92441. /**
  92442. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92443. *
  92444. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92445. */
  92446. final class Filesystem
  92447. {
  92448. public static function createDirectory(string $directory): bool
  92449. {
  92450. return !(!is_dir($directory) && !@mkdir($directory, 0777, \true) && !is_dir($directory));
  92451. }
  92452. /**
  92453. * @psalm-param non-empty-string $path
  92454. *
  92455. * @return false|non-empty-string
  92456. */
  92457. public static function resolveStreamOrFile(string $path): false|string
  92458. {
  92459. if (str_starts_with($path, 'php://') || str_starts_with($path, 'socket://')) {
  92460. return $path;
  92461. }
  92462. $directory = dirname($path);
  92463. if (is_dir($directory)) {
  92464. return realpath($directory) . DIRECTORY_SEPARATOR . basename($path);
  92465. }
  92466. return \false;
  92467. }
  92468. }
  92469. <?php
  92470. declare (strict_types=1);
  92471. /*
  92472. * This file is part of PHPUnit.
  92473. *
  92474. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92475. *
  92476. * For the full copyright and license information, please view the LICENSE
  92477. * file that was distributed with this source code.
  92478. */
  92479. namespace PHPUnit\Util;
  92480. use function array_unshift;
  92481. use function defined;
  92482. use function in_array;
  92483. use function is_file;
  92484. use function realpath;
  92485. use function sprintf;
  92486. use function str_starts_with;
  92487. use PHPUnit\Framework\Exception;
  92488. use PHPUnit\Framework\PhptAssertionFailedError;
  92489. use Throwable;
  92490. /**
  92491. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92492. *
  92493. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92494. */
  92495. final class Filter
  92496. {
  92497. /**
  92498. * @throws Exception
  92499. */
  92500. public static function getFilteredStacktrace(Throwable $t, bool $unwrap = \true): string
  92501. {
  92502. $filteredStacktrace = '';
  92503. if ($t instanceof PhptAssertionFailedError) {
  92504. $eTrace = $t->syntheticTrace();
  92505. $eFile = $t->syntheticFile();
  92506. $eLine = $t->syntheticLine();
  92507. } elseif ($t instanceof Exception) {
  92508. $eTrace = $t->getSerializableTrace();
  92509. $eFile = $t->getFile();
  92510. $eLine = $t->getLine();
  92511. } else {
  92512. if ($unwrap && $t->getPrevious()) {
  92513. $t = $t->getPrevious();
  92514. }
  92515. $eTrace = $t->getTrace();
  92516. $eFile = $t->getFile();
  92517. $eLine = $t->getLine();
  92518. }
  92519. if (!self::frameExists($eTrace, $eFile, $eLine)) {
  92520. array_unshift($eTrace, ['file' => $eFile, 'line' => $eLine]);
  92521. }
  92522. $prefix = defined('__PHPUNIT_PHAR_ROOT__') ? __PHPUNIT_PHAR_ROOT__ : \false;
  92523. $excludeList = new \PHPUnit\Util\ExcludeList();
  92524. foreach ($eTrace as $frame) {
  92525. if (self::shouldPrintFrame($frame, $prefix, $excludeList)) {
  92526. $filteredStacktrace .= sprintf("%s:%s\n", $frame['file'], $frame['line'] ?? '?');
  92527. }
  92528. }
  92529. return $filteredStacktrace;
  92530. }
  92531. private static function shouldPrintFrame(array $frame, false|string $prefix, \PHPUnit\Util\ExcludeList $excludeList): bool
  92532. {
  92533. if (!isset($frame['file'])) {
  92534. return \false;
  92535. }
  92536. $file = $frame['file'];
  92537. $fileIsNotPrefixed = $prefix === \false || !str_starts_with($file, $prefix);
  92538. // @see https://github.com/sebastianbergmann/phpunit/issues/4033
  92539. if (isset($GLOBALS['_SERVER']['SCRIPT_NAME'])) {
  92540. $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
  92541. } else {
  92542. $script = '';
  92543. }
  92544. return $fileIsNotPrefixed && $file !== $script && self::fileIsExcluded($file, $excludeList) && is_file($file);
  92545. }
  92546. private static function fileIsExcluded(string $file, \PHPUnit\Util\ExcludeList $excludeList): bool
  92547. {
  92548. return (empty($GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST']) || !in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'], \true)) && !$excludeList->isExcluded($file);
  92549. }
  92550. private static function frameExists(array $trace, string $file, int $line): bool
  92551. {
  92552. foreach ($trace as $frame) {
  92553. if (isset($frame['file'], $frame['line']) && $frame['file'] === $file && $frame['line'] === $line) {
  92554. return \true;
  92555. }
  92556. }
  92557. return \false;
  92558. }
  92559. }
  92560. <?php
  92561. declare (strict_types=1);
  92562. /*
  92563. * This file is part of PHPUnit.
  92564. *
  92565. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92566. *
  92567. * For the full copyright and license information, please view the LICENSE
  92568. * file that was distributed with this source code.
  92569. */
  92570. namespace PHPUnit\Util;
  92571. use const PHP_MAJOR_VERSION;
  92572. use const PHP_MINOR_VERSION;
  92573. use function array_keys;
  92574. use function array_reverse;
  92575. use function array_shift;
  92576. use function defined;
  92577. use function get_defined_constants;
  92578. use function get_included_files;
  92579. use function in_array;
  92580. use function ini_get_all;
  92581. use function is_array;
  92582. use function is_file;
  92583. use function is_scalar;
  92584. use function preg_match;
  92585. use function serialize;
  92586. use function sprintf;
  92587. use function str_ends_with;
  92588. use function str_starts_with;
  92589. use function strtr;
  92590. use function var_export;
  92591. use Closure;
  92592. /**
  92593. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92594. *
  92595. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92596. */
  92597. final class GlobalState
  92598. {
  92599. /**
  92600. * @psalm-var list<string>
  92601. */
  92602. private const SUPER_GLOBAL_ARRAYS = ['_ENV', '_POST', '_GET', '_COOKIE', '_SERVER', '_FILES', '_REQUEST'];
  92603. /**
  92604. * @psalm-var array<string, array<string, true>>
  92605. */
  92606. private const DEPRECATED_INI_SETTINGS = ['7.3' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.func_overload' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'string.strip_tags' => \true], '7.4' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.func_overload' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'pdo_odbc.db2_instance_name' => \true, 'string.strip_tags' => \true], '8.0' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true], '8.1' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true], '8.2' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true], '8.3' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true]];
  92607. /**
  92608. * @throws Exception
  92609. */
  92610. public static function getIncludedFilesAsString(): string
  92611. {
  92612. return self::processIncludedFilesAsString(get_included_files());
  92613. }
  92614. /**
  92615. * @psalm-param list<string> $files
  92616. *
  92617. * @throws Exception
  92618. */
  92619. public static function processIncludedFilesAsString(array $files): string
  92620. {
  92621. $excludeList = new \PHPUnit\Util\ExcludeList();
  92622. $prefix = \false;
  92623. $result = '';
  92624. if (defined('__PHPUNIT_PHAR__')) {
  92625. $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
  92626. }
  92627. // Do not process bootstrap script
  92628. array_shift($files);
  92629. // If bootstrap script was a Composer bin proxy, skip the second entry as well
  92630. if (str_ends_with(strtr($files[0], '\\', '/'), '/phpunit/phpunit/phpunit')) {
  92631. array_shift($files);
  92632. }
  92633. foreach (array_reverse($files) as $file) {
  92634. if (!empty($GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST']) && in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'], \true)) {
  92635. continue;
  92636. }
  92637. if ($prefix !== \false && str_starts_with($file, $prefix)) {
  92638. continue;
  92639. }
  92640. // Skip virtual file system protocols
  92641. if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) {
  92642. continue;
  92643. }
  92644. if (!$excludeList->isExcluded($file) && is_file($file)) {
  92645. $result = 'require_once \'' . $file . "';\n" . $result;
  92646. }
  92647. }
  92648. return $result;
  92649. }
  92650. public static function getIniSettingsAsString(): string
  92651. {
  92652. $result = '';
  92653. foreach (ini_get_all(null, \false) as $key => $value) {
  92654. if (self::isIniSettingDeprecated($key)) {
  92655. continue;
  92656. }
  92657. $result .= sprintf('@ini_set(%s, %s);' . "\n", self::exportVariable($key), self::exportVariable((string) $value));
  92658. }
  92659. return $result;
  92660. }
  92661. public static function getConstantsAsString(): string
  92662. {
  92663. $constants = get_defined_constants(\true);
  92664. $result = '';
  92665. if (isset($constants['user'])) {
  92666. foreach ($constants['user'] as $name => $value) {
  92667. $result .= sprintf('if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", $name, $name, self::exportVariable($value));
  92668. }
  92669. }
  92670. return $result;
  92671. }
  92672. public static function getGlobalsAsString(): string
  92673. {
  92674. $result = '';
  92675. foreach (self::SUPER_GLOBAL_ARRAYS as $superGlobalArray) {
  92676. if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
  92677. foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
  92678. if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
  92679. continue;
  92680. }
  92681. $result .= sprintf('$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n", $superGlobalArray, $key, self::exportVariable($GLOBALS[$superGlobalArray][$key]));
  92682. }
  92683. }
  92684. }
  92685. $excludeList = self::SUPER_GLOBAL_ARRAYS;
  92686. $excludeList[] = 'GLOBALS';
  92687. foreach (array_keys($GLOBALS) as $key) {
  92688. if (!$GLOBALS[$key] instanceof Closure && !in_array($key, $excludeList, \true)) {
  92689. $result .= sprintf('$GLOBALS[\'%s\'] = %s;' . "\n", $key, self::exportVariable($GLOBALS[$key]));
  92690. }
  92691. }
  92692. return $result;
  92693. }
  92694. private static function exportVariable(mixed $variable): string
  92695. {
  92696. if (is_scalar($variable) || $variable === null || is_array($variable) && self::arrayOnlyContainsScalars($variable)) {
  92697. return var_export($variable, \true);
  92698. }
  92699. return 'unserialize(' . var_export(serialize($variable), \true) . ')';
  92700. }
  92701. private static function arrayOnlyContainsScalars(array $array): bool
  92702. {
  92703. $result = \true;
  92704. foreach ($array as $element) {
  92705. if (is_array($element)) {
  92706. $result = self::arrayOnlyContainsScalars($element);
  92707. } elseif (!is_scalar($element) && $element !== null) {
  92708. $result = \false;
  92709. }
  92710. if (!$result) {
  92711. break;
  92712. }
  92713. }
  92714. return $result;
  92715. }
  92716. private static function isIniSettingDeprecated(string $iniSetting): bool
  92717. {
  92718. return isset(self::DEPRECATED_INI_SETTINGS[PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION][$iniSetting]);
  92719. }
  92720. }
  92721. <?php
  92722. declare (strict_types=1);
  92723. /*
  92724. * This file is part of PHPUnit.
  92725. *
  92726. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92727. *
  92728. * For the full copyright and license information, please view the LICENSE
  92729. * file that was distributed with this source code.
  92730. */
  92731. namespace PHPUnit\Util\Http;
  92732. /**
  92733. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92734. *
  92735. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92736. */
  92737. interface Downloader
  92738. {
  92739. /**
  92740. * @param non-empty-string $url
  92741. */
  92742. public function download(string $url): false|string;
  92743. }
  92744. <?php
  92745. declare (strict_types=1);
  92746. /*
  92747. * This file is part of PHPUnit.
  92748. *
  92749. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92750. *
  92751. * For the full copyright and license information, please view the LICENSE
  92752. * file that was distributed with this source code.
  92753. */
  92754. namespace PHPUnit\Util\Http;
  92755. use function file_get_contents;
  92756. /**
  92757. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92758. *
  92759. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92760. *
  92761. * @codeCoverageIgnore
  92762. */
  92763. final class PhpDownloader implements \PHPUnit\Util\Http\Downloader
  92764. {
  92765. /**
  92766. * @param non-empty-string $url
  92767. */
  92768. public function download(string $url): false|string
  92769. {
  92770. return file_get_contents($url);
  92771. }
  92772. }
  92773. <?php
  92774. declare (strict_types=1);
  92775. /*
  92776. * This file is part of PHPUnit.
  92777. *
  92778. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92779. *
  92780. * For the full copyright and license information, please view the LICENSE
  92781. * file that was distributed with this source code.
  92782. */
  92783. namespace PHPUnit\Util;
  92784. use const JSON_PRETTY_PRINT;
  92785. use const JSON_UNESCAPED_SLASHES;
  92786. use const JSON_UNESCAPED_UNICODE;
  92787. use const SORT_STRING;
  92788. use function is_object;
  92789. use function is_scalar;
  92790. use function json_decode;
  92791. use function json_encode;
  92792. use function json_last_error;
  92793. use function ksort;
  92794. /**
  92795. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92796. *
  92797. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92798. */
  92799. final class Json
  92800. {
  92801. /**
  92802. * @throws InvalidJsonException
  92803. */
  92804. public static function prettify(string $json): string
  92805. {
  92806. $decodedJson = json_decode($json, \false);
  92807. if (json_last_error()) {
  92808. throw new \PHPUnit\Util\InvalidJsonException();
  92809. }
  92810. return json_encode($decodedJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
  92811. }
  92812. /**
  92813. * To allow comparison of JSON strings, first process them into a consistent
  92814. * format so that they can be compared as strings.
  92815. *
  92816. * @return array ($error, $canonicalized_json) The $error parameter is used
  92817. * to indicate an error decoding the json. This is used to avoid ambiguity
  92818. * with JSON strings consisting entirely of 'null' or 'false'.
  92819. */
  92820. public static function canonicalize(string $json): array
  92821. {
  92822. $decodedJson = json_decode($json);
  92823. if (json_last_error()) {
  92824. return [\true, null];
  92825. }
  92826. self::recursiveSort($decodedJson);
  92827. $reencodedJson = json_encode($decodedJson);
  92828. return [\false, $reencodedJson];
  92829. }
  92830. /**
  92831. * JSON object keys are unordered while PHP array keys are ordered.
  92832. *
  92833. * Sort all array keys to ensure both the expected and actual values have
  92834. * their keys in the same order.
  92835. */
  92836. private static function recursiveSort(mixed &$json): void
  92837. {
  92838. // Nulls, empty arrays, and scalars need no further handling.
  92839. if (!$json || is_scalar($json)) {
  92840. return;
  92841. }
  92842. $isObject = is_object($json);
  92843. if ($isObject) {
  92844. // Objects need to be sorted during canonicalization to ensure
  92845. // correct comparsion since JSON objects are unordered. It must be
  92846. // kept as an object so that the value correctly stays as a JSON
  92847. // object instead of potentially being converted to an array. This
  92848. // approach ensures that numeric string JSON keys are preserved and
  92849. // don't risk being flattened due to PHP's array semantics.
  92850. // See #2919, #4584, #4674
  92851. $json = (array) $json;
  92852. ksort($json, SORT_STRING);
  92853. }
  92854. foreach ($json as &$value) {
  92855. self::recursiveSort($value);
  92856. }
  92857. if ($isObject) {
  92858. $json = (object) $json;
  92859. }
  92860. }
  92861. }
  92862. <?php
  92863. declare (strict_types=1);
  92864. /*
  92865. * This file is part of PHPUnit.
  92866. *
  92867. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  92868. *
  92869. * For the full copyright and license information, please view the LICENSE
  92870. * file that was distributed with this source code.
  92871. */
  92872. namespace PHPUnit\Util\PHP;
  92873. use const PHP_BINARY;
  92874. use const PHP_SAPI;
  92875. use function array_keys;
  92876. use function array_merge;
  92877. use function assert;
  92878. use function explode;
  92879. use function file_get_contents;
  92880. use function ini_get_all;
  92881. use function is_file;
  92882. use function restore_error_handler;
  92883. use function set_error_handler;
  92884. use function trim;
  92885. use function unlink;
  92886. use function unserialize;
  92887. use ErrorException;
  92888. use PHPUnit\Event\Code\TestMethodBuilder;
  92889. use PHPUnit\Event\Code\ThrowableBuilder;
  92890. use PHPUnit\Event\Facade;
  92891. use PHPUnit\Event\NoPreviousThrowableException;
  92892. use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
  92893. use PHPUnit\Framework\AssertionFailedError;
  92894. use PHPUnit\Framework\Exception;
  92895. use PHPUnit\Framework\Test;
  92896. use PHPUnit\Framework\TestCase;
  92897. use PHPUnit\Runner\CodeCoverage;
  92898. use PHPUnit\TestRunner\TestResult\PassedTests;
  92899. use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
  92900. /**
  92901. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  92902. *
  92903. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  92904. */
  92905. abstract class AbstractPhpProcess
  92906. {
  92907. protected bool $stderrRedirection = \false;
  92908. protected string $stdin = '';
  92909. protected string $arguments = '';
  92910. /**
  92911. * @psalm-var array<string, string>
  92912. */
  92913. protected array $env = [];
  92914. public static function factory(): self
  92915. {
  92916. return new \PHPUnit\Util\PHP\DefaultPhpProcess();
  92917. }
  92918. /**
  92919. * Defines if should use STDERR redirection or not.
  92920. *
  92921. * Then $stderrRedirection is TRUE, STDERR is redirected to STDOUT.
  92922. */
  92923. public function setUseStderrRedirection(bool $stderrRedirection): void
  92924. {
  92925. $this->stderrRedirection = $stderrRedirection;
  92926. }
  92927. /**
  92928. * Returns TRUE if uses STDERR redirection or FALSE if not.
  92929. */
  92930. public function useStderrRedirection(): bool
  92931. {
  92932. return $this->stderrRedirection;
  92933. }
  92934. /**
  92935. * Sets the input string to be sent via STDIN.
  92936. */
  92937. public function setStdin(string $stdin): void
  92938. {
  92939. $this->stdin = $stdin;
  92940. }
  92941. /**
  92942. * Returns the input string to be sent via STDIN.
  92943. */
  92944. public function getStdin(): string
  92945. {
  92946. return $this->stdin;
  92947. }
  92948. /**
  92949. * Sets the string of arguments to pass to the php job.
  92950. */
  92951. public function setArgs(string $arguments): void
  92952. {
  92953. $this->arguments = $arguments;
  92954. }
  92955. /**
  92956. * Returns the string of arguments to pass to the php job.
  92957. */
  92958. public function getArgs(): string
  92959. {
  92960. return $this->arguments;
  92961. }
  92962. /**
  92963. * Sets the array of environment variables to start the child process with.
  92964. *
  92965. * @psalm-param array<string, string> $env
  92966. */
  92967. public function setEnv(array $env): void
  92968. {
  92969. $this->env = $env;
  92970. }
  92971. /**
  92972. * Returns the array of environment variables to start the child process with.
  92973. */
  92974. public function getEnv(): array
  92975. {
  92976. return $this->env;
  92977. }
  92978. /**
  92979. * Runs a single test in a separate PHP process.
  92980. *
  92981. * @throws \PHPUnit\Runner\Exception
  92982. * @throws Exception
  92983. * @throws MoreThanOneDataSetFromDataProviderException
  92984. * @throws NoPreviousThrowableException
  92985. */
  92986. public function runTestJob(string $job, Test $test, string $processResultFile): void
  92987. {
  92988. $_result = $this->runJob($job);
  92989. $processResult = '';
  92990. if (is_file($processResultFile)) {
  92991. $processResult = file_get_contents($processResultFile);
  92992. @unlink($processResultFile);
  92993. }
  92994. $this->processChildResult($test, $processResult, $_result['stderr']);
  92995. }
  92996. /**
  92997. * Returns the command based into the configurations.
  92998. *
  92999. * @return string[]
  93000. */
  93001. public function getCommand(array $settings, ?string $file = null): array
  93002. {
  93003. $runtime = new Runtime();
  93004. $command = [];
  93005. $command[] = PHP_BINARY;
  93006. if ($runtime->hasPCOV()) {
  93007. $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('pcov'))));
  93008. } elseif ($runtime->hasXdebug()) {
  93009. $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('xdebug'))));
  93010. }
  93011. $command = array_merge($command, $this->settingsToParameters($settings));
  93012. if (PHP_SAPI === 'phpdbg') {
  93013. $command[] = '-qrr';
  93014. if (!$file) {
  93015. $command[] = 's=';
  93016. }
  93017. }
  93018. if ($file) {
  93019. $command[] = '-f';
  93020. $command[] = $file;
  93021. }
  93022. if ($this->arguments) {
  93023. if (!$file) {
  93024. $command[] = '--';
  93025. }
  93026. foreach (explode(' ', $this->arguments) as $arg) {
  93027. $command[] = trim($arg);
  93028. }
  93029. }
  93030. return $command;
  93031. }
  93032. /**
  93033. * Runs a single job (PHP code) using a separate PHP process.
  93034. */
  93035. abstract public function runJob(string $job, array $settings = []): array;
  93036. /**
  93037. * @return list<string>
  93038. */
  93039. protected function settingsToParameters(array $settings): array
  93040. {
  93041. $buffer = [];
  93042. foreach ($settings as $setting) {
  93043. $buffer[] = '-d';
  93044. $buffer[] = $setting;
  93045. }
  93046. return $buffer;
  93047. }
  93048. /**
  93049. * @throws \PHPUnit\Runner\Exception
  93050. * @throws Exception
  93051. * @throws MoreThanOneDataSetFromDataProviderException
  93052. * @throws NoPreviousThrowableException
  93053. */
  93054. private function processChildResult(Test $test, string $stdout, string $stderr): void
  93055. {
  93056. if (!empty($stderr)) {
  93057. $exception = new Exception(trim($stderr));
  93058. assert($test instanceof TestCase);
  93059. Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
  93060. return;
  93061. }
  93062. set_error_handler(
  93063. /**
  93064. * @throws ErrorException
  93065. */
  93066. static function (int $errno, string $errstr, string $errfile, int $errline): never {
  93067. throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
  93068. }
  93069. );
  93070. try {
  93071. $childResult = unserialize($stdout);
  93072. restore_error_handler();
  93073. if ($childResult === \false) {
  93074. $exception = new AssertionFailedError('Test was run in child process and ended unexpectedly');
  93075. assert($test instanceof TestCase);
  93076. Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
  93077. Facade::emitter()->testFinished(TestMethodBuilder::fromTestCase($test), 0);
  93078. }
  93079. } catch (ErrorException $e) {
  93080. restore_error_handler();
  93081. $childResult = \false;
  93082. $exception = new Exception(trim($stdout), 0, $e);
  93083. assert($test instanceof TestCase);
  93084. Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
  93085. }
  93086. if ($childResult !== \false) {
  93087. if (!empty($childResult['output'])) {
  93088. $output = $childResult['output'];
  93089. }
  93090. Facade::instance()->forward($childResult['events']);
  93091. PassedTests::instance()->import($childResult['passedTests']);
  93092. assert($test instanceof TestCase);
  93093. $test->setResult($childResult['testResult']);
  93094. $test->addToAssertionCount($childResult['numAssertions']);
  93095. if (CodeCoverage::instance()->isActive() && $childResult['codeCoverage'] instanceof \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage) {
  93096. CodeCoverage::instance()->codeCoverage()->merge($childResult['codeCoverage']);
  93097. }
  93098. }
  93099. if (!empty($output)) {
  93100. print $output;
  93101. }
  93102. }
  93103. }
  93104. <?php
  93105. declare (strict_types=1);
  93106. /*
  93107. * This file is part of PHPUnit.
  93108. *
  93109. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93110. *
  93111. * For the full copyright and license information, please view the LICENSE
  93112. * file that was distributed with this source code.
  93113. */
  93114. namespace PHPUnit\Util\PHP;
  93115. use function array_merge;
  93116. use function fclose;
  93117. use function file_put_contents;
  93118. use function fwrite;
  93119. use function is_array;
  93120. use function is_resource;
  93121. use function proc_close;
  93122. use function proc_open;
  93123. use function stream_get_contents;
  93124. use function sys_get_temp_dir;
  93125. use function tempnam;
  93126. use function unlink;
  93127. use PHPUnit\Framework\Exception;
  93128. /**
  93129. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93130. *
  93131. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93132. */
  93133. class DefaultPhpProcess extends \PHPUnit\Util\PHP\AbstractPhpProcess
  93134. {
  93135. private ?string $tempFile = null;
  93136. /**
  93137. * Runs a single job (PHP code) using a separate PHP process.
  93138. *
  93139. * @psalm-return array{stdout: string, stderr: string}
  93140. *
  93141. * @throws Exception
  93142. * @throws PhpProcessException
  93143. */
  93144. public function runJob(string $job, array $settings = []): array
  93145. {
  93146. if ($this->stdin) {
  93147. if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'phpunit_')) || file_put_contents($this->tempFile, $job) === \false) {
  93148. throw new \PHPUnit\Util\PHP\PhpProcessException('Unable to write temporary file');
  93149. }
  93150. $job = $this->stdin;
  93151. }
  93152. return $this->runProcess($job, $settings);
  93153. }
  93154. /**
  93155. * Handles creating the child process and returning the STDOUT and STDERR.
  93156. *
  93157. * @psalm-return array{stdout: string, stderr: string}
  93158. *
  93159. * @throws Exception
  93160. * @throws PhpProcessException
  93161. */
  93162. protected function runProcess(string $job, array $settings): array
  93163. {
  93164. $env = null;
  93165. if ($this->env) {
  93166. $env = $_SERVER ?? [];
  93167. unset($env['argv'], $env['argc']);
  93168. $env = array_merge($env, $this->env);
  93169. foreach ($env as $envKey => $envVar) {
  93170. if (is_array($envVar)) {
  93171. unset($env[$envKey]);
  93172. }
  93173. }
  93174. }
  93175. $pipeSpec = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
  93176. if ($this->stderrRedirection) {
  93177. $pipeSpec[2] = ['redirect', 1];
  93178. }
  93179. $process = proc_open($this->getCommand($settings, $this->tempFile), $pipeSpec, $pipes, null, $env);
  93180. if (!is_resource($process)) {
  93181. throw new \PHPUnit\Util\PHP\PhpProcessException('Unable to spawn worker process');
  93182. }
  93183. if ($job) {
  93184. $this->process($pipes[0], $job);
  93185. }
  93186. fclose($pipes[0]);
  93187. $stderr = $stdout = '';
  93188. if (isset($pipes[1])) {
  93189. $stdout = stream_get_contents($pipes[1]);
  93190. fclose($pipes[1]);
  93191. }
  93192. if (isset($pipes[2])) {
  93193. $stderr = stream_get_contents($pipes[2]);
  93194. fclose($pipes[2]);
  93195. }
  93196. proc_close($process);
  93197. $this->cleanup();
  93198. return ['stdout' => $stdout, 'stderr' => $stderr];
  93199. }
  93200. /**
  93201. * @param resource $pipe
  93202. */
  93203. protected function process($pipe, string $job): void
  93204. {
  93205. fwrite($pipe, $job);
  93206. }
  93207. protected function cleanup(): void
  93208. {
  93209. if ($this->tempFile) {
  93210. unlink($this->tempFile);
  93211. }
  93212. }
  93213. }
  93214. <?php declare(strict_types=1);
  93215. use PHPUnit\Event\Facade;
  93216. use PHPUnit\Runner\CodeCoverage;
  93217. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  93218. use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
  93219. use PHPUnit\TextUI\Configuration\PhpHandler;
  93220. use PHPUnit\TestRunner\TestResult\PassedTests;
  93221. // php://stdout does not obey output buffering. Any output would break
  93222. // unserialization of child process results in the parent process.
  93223. if (!defined('STDOUT')) {
  93224. define('STDOUT', fopen('php://temp', 'w+b'));
  93225. define('STDERR', fopen('php://stderr', 'wb'));
  93226. }
  93227. {iniSettings}
  93228. ini_set('display_errors', 'stderr');
  93229. set_include_path('{include_path}');
  93230. $composerAutoload = {composerAutoload};
  93231. $phar = {phar};
  93232. ob_start();
  93233. if ($composerAutoload) {
  93234. require_once $composerAutoload;
  93235. define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
  93236. } else if ($phar) {
  93237. require $phar;
  93238. }
  93239. function __phpunit_run_isolated_test()
  93240. {
  93241. $dispatcher = Facade::instance()->initForIsolation(
  93242. PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(
  93243. {offsetSeconds},
  93244. {offsetNanoseconds}
  93245. ),
  93246. {exportObjects},
  93247. );
  93248. require_once '{filename}';
  93249. if ({collectCodeCoverageInformation}) {
  93250. CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true);
  93251. CodeCoverage::instance()->ignoreLines({linesToBeIgnored});
  93252. }
  93253. $test = new {className}('{name}');
  93254. $test->setData('{dataName}', unserialize('{data}'));
  93255. $test->setDependencyInput(unserialize('{dependencyInput}'));
  93256. $test->setInIsolation(true);
  93257. ob_end_clean();
  93258. $test->run();
  93259. $output = '';
  93260. if (!$test->expectsOutput()) {
  93261. $output = $test->output();
  93262. }
  93263. ini_set('xdebug.scream', '0');
  93264. // Not every STDOUT target stream is rewindable
  93265. @rewind(STDOUT);
  93266. if ($stdout = @stream_get_contents(STDOUT)) {
  93267. $output = $stdout . $output;
  93268. $streamMetaData = stream_get_meta_data(STDOUT);
  93269. if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) {
  93270. @ftruncate(STDOUT, 0);
  93271. @rewind(STDOUT);
  93272. }
  93273. }
  93274. file_put_contents(
  93275. '{processResultFile}',
  93276. serialize(
  93277. [
  93278. 'testResult' => $test->result(),
  93279. 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null,
  93280. 'numAssertions' => $test->numberOfAssertionsPerformed(),
  93281. 'output' => $output,
  93282. 'events' => $dispatcher->flush(),
  93283. 'passedTests' => PassedTests::instance()
  93284. ]
  93285. )
  93286. );
  93287. }
  93288. function __phpunit_error_handler($errno, $errstr, $errfile, $errline)
  93289. {
  93290. return true;
  93291. }
  93292. set_error_handler('__phpunit_error_handler');
  93293. {constants}
  93294. {included_files}
  93295. {globals}
  93296. restore_error_handler();
  93297. ConfigurationRegistry::loadFrom('{serializedConfiguration}');
  93298. (new PhpHandler)->handle(ConfigurationRegistry::get()->php());
  93299. if ('{bootstrap}' !== '') {
  93300. require_once '{bootstrap}';
  93301. }
  93302. __phpunit_run_isolated_test();
  93303. <?php declare(strict_types=1);
  93304. use PHPUnit\Event\Facade;
  93305. use PHPUnit\Runner\CodeCoverage;
  93306. use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
  93307. use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
  93308. use PHPUnit\TextUI\Configuration\PhpHandler;
  93309. use PHPUnit\TestRunner\TestResult\PassedTests;
  93310. // php://stdout does not obey output buffering. Any output would break
  93311. // unserialization of child process results in the parent process.
  93312. if (!defined('STDOUT')) {
  93313. define('STDOUT', fopen('php://temp', 'w+b'));
  93314. define('STDERR', fopen('php://stderr', 'wb'));
  93315. }
  93316. {iniSettings}
  93317. ini_set('display_errors', 'stderr');
  93318. set_include_path('{include_path}');
  93319. $composerAutoload = {composerAutoload};
  93320. $phar = {phar};
  93321. ob_start();
  93322. if ($composerAutoload) {
  93323. require_once $composerAutoload;
  93324. define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
  93325. } else if ($phar) {
  93326. require $phar;
  93327. }
  93328. function __phpunit_run_isolated_test()
  93329. {
  93330. $dispatcher = Facade::instance()->initForIsolation(
  93331. PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(
  93332. {offsetSeconds},
  93333. {offsetNanoseconds}
  93334. ),
  93335. {exportObjects},
  93336. );
  93337. require_once '{filename}';
  93338. if ({collectCodeCoverageInformation}) {
  93339. CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true);
  93340. CodeCoverage::instance()->ignoreLines({linesToBeIgnored});
  93341. }
  93342. $test = new {className}('{methodName}');
  93343. $test->setData('{dataName}', unserialize('{data}'));
  93344. $test->setDependencyInput(unserialize('{dependencyInput}'));
  93345. $test->setInIsolation(true);
  93346. ob_end_clean();
  93347. $test->run();
  93348. $output = '';
  93349. if (!$test->expectsOutput()) {
  93350. $output = $test->output();
  93351. }
  93352. ini_set('xdebug.scream', '0');
  93353. // Not every STDOUT target stream is rewindable
  93354. @rewind(STDOUT);
  93355. if ($stdout = @stream_get_contents(STDOUT)) {
  93356. $output = $stdout . $output;
  93357. $streamMetaData = stream_get_meta_data(STDOUT);
  93358. if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) {
  93359. @ftruncate(STDOUT, 0);
  93360. @rewind(STDOUT);
  93361. }
  93362. }
  93363. file_put_contents(
  93364. '{processResultFile}',
  93365. serialize(
  93366. [
  93367. 'testResult' => $test->result(),
  93368. 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null,
  93369. 'numAssertions' => $test->numberOfAssertionsPerformed(),
  93370. 'output' => $output,
  93371. 'events' => $dispatcher->flush(),
  93372. 'passedTests' => PassedTests::instance()
  93373. ]
  93374. )
  93375. );
  93376. }
  93377. function __phpunit_error_handler($errno, $errstr, $errfile, $errline)
  93378. {
  93379. return true;
  93380. }
  93381. set_error_handler('__phpunit_error_handler');
  93382. {constants}
  93383. {included_files}
  93384. {globals}
  93385. restore_error_handler();
  93386. ConfigurationRegistry::loadFrom('{serializedConfiguration}');
  93387. (new PhpHandler)->handle(ConfigurationRegistry::get()->php());
  93388. if ('{bootstrap}' !== '') {
  93389. require_once '{bootstrap}';
  93390. }
  93391. __phpunit_run_isolated_test();
  93392. <?php declare(strict_types=1);
  93393. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
  93394. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Selector;
  93395. use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
  93396. $composerAutoload = {composerAutoload};
  93397. $phar = {phar};
  93398. ob_start();
  93399. $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'][] = '{job}';
  93400. if ($composerAutoload) {
  93401. require_once $composerAutoload;
  93402. define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
  93403. } else if ($phar) {
  93404. require $phar;
  93405. }
  93406. $coverage = null;
  93407. if ('{bootstrap}' !== '') {
  93408. require_once '{bootstrap}';
  93409. }
  93410. if (class_exists('PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage')) {
  93411. $filter = new Filter;
  93412. $coverage = new CodeCoverage(
  93413. (new Selector)->{driverMethod}($filter),
  93414. $filter
  93415. );
  93416. if ({codeCoverageCacheDirectory}) {
  93417. $coverage->cacheStaticAnalysis({codeCoverageCacheDirectory});
  93418. }
  93419. $coverage->start(__FILE__);
  93420. }
  93421. register_shutdown_function(
  93422. function() use ($coverage) {
  93423. $output = null;
  93424. if ($coverage) {
  93425. $output = $coverage->stop();
  93426. }
  93427. file_put_contents('{coverageFile}', serialize($output));
  93428. }
  93429. );
  93430. ob_end_clean();
  93431. require '{job}';
  93432. <?php
  93433. declare (strict_types=1);
  93434. /*
  93435. * This file is part of PHPUnit.
  93436. *
  93437. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93438. *
  93439. * For the full copyright and license information, please view the LICENSE
  93440. * file that was distributed with this source code.
  93441. */
  93442. namespace PHPUnit\Util;
  93443. use function array_keys;
  93444. use function array_merge;
  93445. use function array_reverse;
  93446. use PHPUnit\Framework\Assert;
  93447. use PHPUnit\Framework\TestCase;
  93448. use ReflectionClass;
  93449. use ReflectionException;
  93450. use ReflectionMethod;
  93451. /**
  93452. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93453. *
  93454. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93455. */
  93456. final class Reflection
  93457. {
  93458. /**
  93459. * @psalm-param class-string $className
  93460. * @psalm-param non-empty-string $methodName
  93461. *
  93462. * @psalm-return array{file: non-empty-string, line: non-negative-int}
  93463. */
  93464. public static function sourceLocationFor(string $className, string $methodName): array
  93465. {
  93466. try {
  93467. $reflector = new ReflectionMethod($className, $methodName);
  93468. $file = $reflector->getFileName();
  93469. $line = $reflector->getStartLine();
  93470. } catch (ReflectionException) {
  93471. $file = 'unknown';
  93472. $line = 0;
  93473. }
  93474. return ['file' => $file, 'line' => $line];
  93475. }
  93476. /**
  93477. * @psalm-return list<ReflectionMethod>
  93478. */
  93479. public static function publicMethodsInTestClass(ReflectionClass $class): array
  93480. {
  93481. return self::filterAndSortMethods($class, ReflectionMethod::IS_PUBLIC, \true);
  93482. }
  93483. /**
  93484. * @psalm-return list<ReflectionMethod>
  93485. */
  93486. public static function methodsInTestClass(ReflectionClass $class): array
  93487. {
  93488. return self::filterAndSortMethods($class, null, \false);
  93489. }
  93490. /**
  93491. * @psalm-return list<ReflectionMethod>
  93492. */
  93493. private static function filterAndSortMethods(ReflectionClass $class, ?int $filter, bool $sortHighestToLowest): array
  93494. {
  93495. $methodsByClass = [];
  93496. foreach ($class->getMethods($filter) as $method) {
  93497. $declaringClassName = $method->getDeclaringClass()->getName();
  93498. if ($declaringClassName === TestCase::class) {
  93499. continue;
  93500. }
  93501. if ($declaringClassName === Assert::class) {
  93502. continue;
  93503. }
  93504. if (!isset($methodsByClass[$declaringClassName])) {
  93505. $methodsByClass[$declaringClassName] = [];
  93506. }
  93507. $methodsByClass[$declaringClassName][] = $method;
  93508. }
  93509. $classNames = array_keys($methodsByClass);
  93510. if ($sortHighestToLowest) {
  93511. $classNames = array_reverse($classNames);
  93512. }
  93513. $methods = [];
  93514. foreach ($classNames as $className) {
  93515. $methods = array_merge($methods, $methodsByClass[$className]);
  93516. }
  93517. return $methods;
  93518. }
  93519. }
  93520. <?php
  93521. declare (strict_types=1);
  93522. /*
  93523. * This file is part of PHPUnit.
  93524. *
  93525. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93526. *
  93527. * For the full copyright and license information, please view the LICENSE
  93528. * file that was distributed with this source code.
  93529. */
  93530. namespace PHPUnit\Util;
  93531. use function str_starts_with;
  93532. use PHPUnit\Metadata\Parser\Registry;
  93533. use ReflectionMethod;
  93534. /**
  93535. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93536. *
  93537. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93538. */
  93539. final class Test
  93540. {
  93541. public static function isTestMethod(ReflectionMethod $method): bool
  93542. {
  93543. if (!$method->isPublic()) {
  93544. return \false;
  93545. }
  93546. if (str_starts_with($method->getName(), 'test')) {
  93547. return \true;
  93548. }
  93549. $metadata = Registry::parser()->forMethod($method->getDeclaringClass()->getName(), $method->getName());
  93550. return $metadata->isTest()->isNotEmpty();
  93551. }
  93552. }
  93553. <?php
  93554. declare (strict_types=1);
  93555. /*
  93556. * This file is part of PHPUnit.
  93557. *
  93558. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93559. *
  93560. * For the full copyright and license information, please view the LICENSE
  93561. * file that was distributed with this source code.
  93562. */
  93563. namespace PHPUnit\Util;
  93564. use function trim;
  93565. use PHPUnit\Framework\ExpectationFailedException;
  93566. use PHPUnit\Framework\PhptAssertionFailedError;
  93567. use PHPUnit\Framework\SelfDescribing;
  93568. use PHPUnit\Runner\ErrorException;
  93569. use Throwable;
  93570. /**
  93571. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93572. *
  93573. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93574. */
  93575. final class ThrowableToStringMapper
  93576. {
  93577. public static function map(Throwable $t): string
  93578. {
  93579. if ($t instanceof ErrorException) {
  93580. return $t->getMessage();
  93581. }
  93582. if ($t instanceof SelfDescribing) {
  93583. $buffer = $t->toString();
  93584. if ($t instanceof ExpectationFailedException && $t->getComparisonFailure()) {
  93585. $buffer .= $t->getComparisonFailure()->getDiff();
  93586. }
  93587. if ($t instanceof PhptAssertionFailedError) {
  93588. $buffer .= $t->diff();
  93589. }
  93590. if (!empty($buffer)) {
  93591. $buffer = trim($buffer) . "\n";
  93592. }
  93593. return $buffer;
  93594. }
  93595. return $t::class . ': ' . $t->getMessage() . "\n";
  93596. }
  93597. }
  93598. <?php
  93599. declare (strict_types=1);
  93600. /*
  93601. * This file is part of PHPUnit.
  93602. *
  93603. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93604. *
  93605. * For the full copyright and license information, please view the LICENSE
  93606. * file that was distributed with this source code.
  93607. */
  93608. namespace PHPUnit\Util;
  93609. use function in_array;
  93610. /**
  93611. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93612. *
  93613. * @psalm-immutable
  93614. */
  93615. final class VersionComparisonOperator
  93616. {
  93617. /**
  93618. * @psalm-var '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
  93619. */
  93620. private readonly string $operator;
  93621. /**
  93622. * @psalm-param '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
  93623. *
  93624. * @throws InvalidVersionOperatorException
  93625. */
  93626. public function __construct(string $operator)
  93627. {
  93628. $this->ensureOperatorIsValid($operator);
  93629. $this->operator = $operator;
  93630. }
  93631. /**
  93632. * @psalm-return '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
  93633. */
  93634. public function asString(): string
  93635. {
  93636. return $this->operator;
  93637. }
  93638. /**
  93639. * @psalm-param '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
  93640. *
  93641. * @throws InvalidVersionOperatorException
  93642. */
  93643. private function ensureOperatorIsValid(string $operator): void
  93644. {
  93645. if (!in_array($operator, ['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'], \true)) {
  93646. throw new \PHPUnit\Util\InvalidVersionOperatorException($operator);
  93647. }
  93648. }
  93649. }
  93650. <?php
  93651. declare (strict_types=1);
  93652. /*
  93653. * This file is part of PHPUnit.
  93654. *
  93655. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93656. *
  93657. * For the full copyright and license information, please view the LICENSE
  93658. * file that was distributed with this source code.
  93659. */
  93660. namespace PHPUnit\Util\Xml;
  93661. use const PHP_OS_FAMILY;
  93662. use function chdir;
  93663. use function dirname;
  93664. use function error_reporting;
  93665. use function file_get_contents;
  93666. use function getcwd;
  93667. use function libxml_get_errors;
  93668. use function libxml_use_internal_errors;
  93669. use function sprintf;
  93670. use DOMDocument;
  93671. /**
  93672. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93673. *
  93674. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93675. */
  93676. final class Loader
  93677. {
  93678. /**
  93679. * @throws XmlException
  93680. */
  93681. public function loadFile(string $filename): DOMDocument
  93682. {
  93683. $reporting = error_reporting(0);
  93684. $contents = file_get_contents($filename);
  93685. error_reporting($reporting);
  93686. if ($contents === \false) {
  93687. throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not read XML from file "%s"', $filename));
  93688. }
  93689. return $this->load($contents, $filename);
  93690. }
  93691. /**
  93692. * @throws XmlException
  93693. */
  93694. public function load(string $actual, ?string $filename = null): DOMDocument
  93695. {
  93696. if ($actual === '') {
  93697. if ($filename === null) {
  93698. throw new \PHPUnit\Util\Xml\XmlException('Could not parse XML from empty string');
  93699. }
  93700. throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not parse XML from empty file "%s"', $filename));
  93701. }
  93702. $document = new DOMDocument();
  93703. $document->preserveWhiteSpace = \false;
  93704. $internal = libxml_use_internal_errors(\true);
  93705. $message = '';
  93706. $reporting = error_reporting(0);
  93707. // Required for XInclude
  93708. if ($filename !== null) {
  93709. // Required for XInclude on Windows
  93710. if (PHP_OS_FAMILY === 'Windows') {
  93711. $cwd = getcwd();
  93712. @chdir(dirname($filename));
  93713. }
  93714. $document->documentURI = $filename;
  93715. }
  93716. $loaded = $document->loadXML($actual);
  93717. if ($filename !== null) {
  93718. $document->xinclude();
  93719. }
  93720. foreach (libxml_get_errors() as $error) {
  93721. $message .= "\n" . $error->message;
  93722. }
  93723. libxml_use_internal_errors($internal);
  93724. error_reporting($reporting);
  93725. if (isset($cwd)) {
  93726. @chdir($cwd);
  93727. }
  93728. if ($loaded === \false || $message !== '') {
  93729. if ($filename !== null) {
  93730. throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not load "%s"%s', $filename, $message !== '' ? ":\n" . $message : ''));
  93731. }
  93732. if ($message === '') {
  93733. $message = 'Could not load XML for unknown reason';
  93734. }
  93735. throw new \PHPUnit\Util\Xml\XmlException($message);
  93736. }
  93737. return $document;
  93738. }
  93739. }
  93740. <?php
  93741. declare (strict_types=1);
  93742. /*
  93743. * This file is part of PHPUnit.
  93744. *
  93745. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  93746. *
  93747. * For the full copyright and license information, please view the LICENSE
  93748. * file that was distributed with this source code.
  93749. */
  93750. namespace PHPUnit\Util;
  93751. use const ENT_QUOTES;
  93752. use function htmlspecialchars;
  93753. use function mb_convert_encoding;
  93754. use function ord;
  93755. use function preg_replace;
  93756. use function strlen;
  93757. /**
  93758. * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
  93759. *
  93760. * @internal This class is not covered by the backward compatibility promise for PHPUnit
  93761. */
  93762. final class Xml
  93763. {
  93764. /**
  93765. * Escapes a string for the use in XML documents.
  93766. *
  93767. * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
  93768. * and FFFF (not even as character reference).
  93769. *
  93770. * @see https://www.w3.org/TR/xml/#charsets
  93771. */
  93772. public static function prepareString(string $string): string
  93773. {
  93774. return preg_replace('/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/', '', htmlspecialchars(self::convertToUtf8($string), ENT_QUOTES));
  93775. }
  93776. private static function convertToUtf8(string $string): string
  93777. {
  93778. if (!self::isUtf8($string)) {
  93779. $string = mb_convert_encoding($string, 'UTF-8');
  93780. }
  93781. return $string;
  93782. }
  93783. private static function isUtf8(string $string): bool
  93784. {
  93785. $length = strlen($string);
  93786. for ($i = 0; $i < $length; $i++) {
  93787. if (ord($string[$i]) < 0x80) {
  93788. $n = 0;
  93789. } elseif ((ord($string[$i]) & 0xe0) === 0xc0) {
  93790. $n = 1;
  93791. } elseif ((ord($string[$i]) & 0xf0) === 0xe0) {
  93792. $n = 2;
  93793. } elseif ((ord($string[$i]) & 0xf0) === 0xf0) {
  93794. $n = 3;
  93795. } else {
  93796. return \false;
  93797. }
  93798. for ($j = 0; $j < $n; $j++) {
  93799. if (++$i === $length || (ord($string[$i]) & 0xc0) !== 0x80) {
  93800. return \false;
  93801. }
  93802. }
  93803. }
  93804. return \true;
  93805. }
  93806. }
  93807. <?xml version="1.0"?>
  93808. <bom xmlns="http://cyclonedx.org/schema/bom/1.4">
  93809. <components>
  93810. <component type="library">
  93811. <group>phpunit</group>
  93812. <name>phpunit</name>
  93813. <version>10.5.40</version>
  93814. <description>The PHP Unit Testing framework.</description>
  93815. <licenses>
  93816. <license>
  93817. <id>BSD-3-Clause</id>
  93818. </license>
  93819. </licenses>
  93820. <purl>pkg:composer/phpunit/phpunit@10.5.40</purl>
  93821. </component>
  93822. <component type="library">
  93823. <group>myclabs</group>
  93824. <name>deep-copy</name>
  93825. <version>1.12.1</version>
  93826. <description>Create deep copies (clones) of your objects</description>
  93827. <licenses>
  93828. <license>
  93829. <id>MIT</id>
  93830. </license>
  93831. </licenses>
  93832. <purl>pkg:composer/myclabs/deep-copy@1.12.1</purl>
  93833. </component>
  93834. <component type="library">
  93835. <group>nikic</group>
  93836. <name>php-parser</name>
  93837. <version>v5.3.1</version>
  93838. <description>A PHP parser written in PHP</description>
  93839. <licenses>
  93840. <license>
  93841. <id>BSD-3-Clause</id>
  93842. </license>
  93843. </licenses>
  93844. <purl>pkg:composer/nikic/php-parser@v5.3.1</purl>
  93845. </component>
  93846. <component type="library">
  93847. <group>phar-io</group>
  93848. <name>manifest</name>
  93849. <version>2.0.4</version>
  93850. <description>Component for reading phar.io manifest information from a PHP Archive (PHAR)</description>
  93851. <licenses>
  93852. <license>
  93853. <id>BSD-3-Clause</id>
  93854. </license>
  93855. </licenses>
  93856. <purl>pkg:composer/phar-io/manifest@2.0.4</purl>
  93857. </component>
  93858. <component type="library">
  93859. <group>phar-io</group>
  93860. <name>version</name>
  93861. <version>3.2.1</version>
  93862. <description>Library for handling version information and constraints</description>
  93863. <licenses>
  93864. <license>
  93865. <id>BSD-3-Clause</id>
  93866. </license>
  93867. </licenses>
  93868. <purl>pkg:composer/phar-io/version@3.2.1</purl>
  93869. </component>
  93870. <component type="library">
  93871. <group>phpunit</group>
  93872. <name>php-code-coverage</name>
  93873. <version>10.1.16</version>
  93874. <description>Library that provides collection, processing, and rendering functionality for PHP code coverage information.</description>
  93875. <licenses>
  93876. <license>
  93877. <id>BSD-3-Clause</id>
  93878. </license>
  93879. </licenses>
  93880. <purl>pkg:composer/phpunit/php-code-coverage@10.1.16</purl>
  93881. </component>
  93882. <component type="library">
  93883. <group>phpunit</group>
  93884. <name>php-file-iterator</name>
  93885. <version>4.1.0</version>
  93886. <description>FilterIterator implementation that filters files based on a list of suffixes.</description>
  93887. <licenses>
  93888. <license>
  93889. <id>BSD-3-Clause</id>
  93890. </license>
  93891. </licenses>
  93892. <purl>pkg:composer/phpunit/php-file-iterator@4.1.0</purl>
  93893. </component>
  93894. <component type="library">
  93895. <group>phpunit</group>
  93896. <name>php-invoker</name>
  93897. <version>4.0.0</version>
  93898. <description>Invoke callables with a timeout</description>
  93899. <licenses>
  93900. <license>
  93901. <id>BSD-3-Clause</id>
  93902. </license>
  93903. </licenses>
  93904. <purl>pkg:composer/phpunit/php-invoker@4.0.0</purl>
  93905. </component>
  93906. <component type="library">
  93907. <group>phpunit</group>
  93908. <name>php-text-template</name>
  93909. <version>3.0.1</version>
  93910. <description>Simple template engine.</description>
  93911. <licenses>
  93912. <license>
  93913. <id>BSD-3-Clause</id>
  93914. </license>
  93915. </licenses>
  93916. <purl>pkg:composer/phpunit/php-text-template@3.0.1</purl>
  93917. </component>
  93918. <component type="library">
  93919. <group>phpunit</group>
  93920. <name>php-timer</name>
  93921. <version>6.0.0</version>
  93922. <description>Utility class for timing</description>
  93923. <licenses>
  93924. <license>
  93925. <id>BSD-3-Clause</id>
  93926. </license>
  93927. </licenses>
  93928. <purl>pkg:composer/phpunit/php-timer@6.0.0</purl>
  93929. </component>
  93930. <component type="library">
  93931. <group>sebastian</group>
  93932. <name>cli-parser</name>
  93933. <version>2.0.1</version>
  93934. <description>Library for parsing CLI options</description>
  93935. <licenses>
  93936. <license>
  93937. <id>BSD-3-Clause</id>
  93938. </license>
  93939. </licenses>
  93940. <purl>pkg:composer/sebastian/cli-parser@2.0.1</purl>
  93941. </component>
  93942. <component type="library">
  93943. <group>sebastian</group>
  93944. <name>code-unit</name>
  93945. <version>2.0.0</version>
  93946. <description>Collection of value objects that represent the PHP code units</description>
  93947. <licenses>
  93948. <license>
  93949. <id>BSD-3-Clause</id>
  93950. </license>
  93951. </licenses>
  93952. <purl>pkg:composer/sebastian/code-unit@2.0.0</purl>
  93953. </component>
  93954. <component type="library">
  93955. <group>sebastian</group>
  93956. <name>code-unit-reverse-lookup</name>
  93957. <version>3.0.0</version>
  93958. <description>Looks up which function or method a line of code belongs to</description>
  93959. <licenses>
  93960. <license>
  93961. <id>BSD-3-Clause</id>
  93962. </license>
  93963. </licenses>
  93964. <purl>pkg:composer/sebastian/code-unit-reverse-lookup@3.0.0</purl>
  93965. </component>
  93966. <component type="library">
  93967. <group>sebastian</group>
  93968. <name>comparator</name>
  93969. <version>5.0.3</version>
  93970. <description>Provides the functionality to compare PHP values for equality</description>
  93971. <licenses>
  93972. <license>
  93973. <id>BSD-3-Clause</id>
  93974. </license>
  93975. </licenses>
  93976. <purl>pkg:composer/sebastian/comparator@5.0.3</purl>
  93977. </component>
  93978. <component type="library">
  93979. <group>sebastian</group>
  93980. <name>complexity</name>
  93981. <version>3.2.0</version>
  93982. <description>Library for calculating the complexity of PHP code units</description>
  93983. <licenses>
  93984. <license>
  93985. <id>BSD-3-Clause</id>
  93986. </license>
  93987. </licenses>
  93988. <purl>pkg:composer/sebastian/complexity@3.2.0</purl>
  93989. </component>
  93990. <component type="library">
  93991. <group>sebastian</group>
  93992. <name>diff</name>
  93993. <version>5.1.1</version>
  93994. <description>Diff implementation</description>
  93995. <licenses>
  93996. <license>
  93997. <id>BSD-3-Clause</id>
  93998. </license>
  93999. </licenses>
  94000. <purl>pkg:composer/sebastian/diff@5.1.1</purl>
  94001. </component>
  94002. <component type="library">
  94003. <group>sebastian</group>
  94004. <name>environment</name>
  94005. <version>6.1.0</version>
  94006. <description>Provides functionality to handle HHVM/PHP environments</description>
  94007. <licenses>
  94008. <license>
  94009. <id>BSD-3-Clause</id>
  94010. </license>
  94011. </licenses>
  94012. <purl>pkg:composer/sebastian/environment@6.1.0</purl>
  94013. </component>
  94014. <component type="library">
  94015. <group>sebastian</group>
  94016. <name>exporter</name>
  94017. <version>5.1.2</version>
  94018. <description>Provides the functionality to export PHP variables for visualization</description>
  94019. <licenses>
  94020. <license>
  94021. <id>BSD-3-Clause</id>
  94022. </license>
  94023. </licenses>
  94024. <purl>pkg:composer/sebastian/exporter@5.1.2</purl>
  94025. </component>
  94026. <component type="library">
  94027. <group>sebastian</group>
  94028. <name>global-state</name>
  94029. <version>6.0.2</version>
  94030. <description>Snapshotting of global state</description>
  94031. <licenses>
  94032. <license>
  94033. <id>BSD-3-Clause</id>
  94034. </license>
  94035. </licenses>
  94036. <purl>pkg:composer/sebastian/global-state@6.0.2</purl>
  94037. </component>
  94038. <component type="library">
  94039. <group>sebastian</group>
  94040. <name>lines-of-code</name>
  94041. <version>2.0.2</version>
  94042. <description>Library for counting the lines of code in PHP source code</description>
  94043. <licenses>
  94044. <license>
  94045. <id>BSD-3-Clause</id>
  94046. </license>
  94047. </licenses>
  94048. <purl>pkg:composer/sebastian/lines-of-code@2.0.2</purl>
  94049. </component>
  94050. <component type="library">
  94051. <group>sebastian</group>
  94052. <name>object-enumerator</name>
  94053. <version>5.0.0</version>
  94054. <description>Traverses array structures and object graphs to enumerate all referenced objects</description>
  94055. <licenses>
  94056. <license>
  94057. <id>BSD-3-Clause</id>
  94058. </license>
  94059. </licenses>
  94060. <purl>pkg:composer/sebastian/object-enumerator@5.0.0</purl>
  94061. </component>
  94062. <component type="library">
  94063. <group>sebastian</group>
  94064. <name>object-reflector</name>
  94065. <version>3.0.0</version>
  94066. <description>Allows reflection of object attributes, including inherited and non-public ones</description>
  94067. <licenses>
  94068. <license>
  94069. <id>BSD-3-Clause</id>
  94070. </license>
  94071. </licenses>
  94072. <purl>pkg:composer/sebastian/object-reflector@3.0.0</purl>
  94073. </component>
  94074. <component type="library">
  94075. <group>sebastian</group>
  94076. <name>recursion-context</name>
  94077. <version>5.0.0</version>
  94078. <description>Provides functionality to recursively process PHP variables</description>
  94079. <licenses>
  94080. <license>
  94081. <id>BSD-3-Clause</id>
  94082. </license>
  94083. </licenses>
  94084. <purl>pkg:composer/sebastian/recursion-context@5.0.0</purl>
  94085. </component>
  94086. <component type="library">
  94087. <group>sebastian</group>
  94088. <name>type</name>
  94089. <version>4.0.0</version>
  94090. <description>Collection of value objects that represent the types of the PHP type system</description>
  94091. <licenses>
  94092. <license>
  94093. <id>BSD-3-Clause</id>
  94094. </license>
  94095. </licenses>
  94096. <purl>pkg:composer/sebastian/type@4.0.0</purl>
  94097. </component>
  94098. <component type="library">
  94099. <group>sebastian</group>
  94100. <name>version</name>
  94101. <version>4.0.1</version>
  94102. <description>Library that helps with managing the version number of Git-hosted PHP projects</description>
  94103. <licenses>
  94104. <license>
  94105. <id>BSD-3-Clause</id>
  94106. </license>
  94107. </licenses>
  94108. <purl>pkg:composer/sebastian/version@4.0.1</purl>
  94109. </component>
  94110. <component type="library">
  94111. <group>theseer</group>
  94112. <name>tokenizer</name>
  94113. <version>1.2.3</version>
  94114. <description>A small library for converting tokenized PHP source code into XML and potentially other formats</description>
  94115. <licenses>
  94116. <license>
  94117. <id>BSD-3-Clause</id>
  94118. </license>
  94119. </licenses>
  94120. <purl>pkg:composer/theseer/tokenizer@1.2.3</purl>
  94121. </component>
  94122. </components>
  94123. </bom>
  94124. <?xml version="1.0" encoding="UTF-8"?>
  94125. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  94126. <xs:annotation>
  94127. <xs:documentation source="https://phpunit.de/documentation.html">
  94128. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.0 may be structured.
  94129. </xs:documentation>
  94130. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  94131. </xs:annotation>
  94132. <xs:element name="phpunit" type="phpUnitType">
  94133. <xs:annotation>
  94134. <xs:documentation>Root Element</xs:documentation>
  94135. </xs:annotation>
  94136. </xs:element>
  94137. <xs:complexType name="coverageType">
  94138. <xs:all>
  94139. <xs:element name="include" minOccurs="0" maxOccurs="1">
  94140. <xs:complexType>
  94141. <xs:group ref="pathGroup"/>
  94142. </xs:complexType>
  94143. </xs:element>
  94144. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  94145. <xs:complexType>
  94146. <xs:group ref="pathGroup"/>
  94147. </xs:complexType>
  94148. </xs:element>
  94149. <xs:element name="report" minOccurs="0" maxOccurs="1">
  94150. <xs:complexType>
  94151. <xs:group ref="coverageReportGroup"/>
  94152. </xs:complexType>
  94153. </xs:element>
  94154. </xs:all>
  94155. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94156. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  94157. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  94158. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  94159. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  94160. </xs:complexType>
  94161. <xs:complexType name="loggingType">
  94162. <xs:group ref="loggingGroup"/>
  94163. </xs:complexType>
  94164. <xs:complexType name="groupsType">
  94165. <xs:choice>
  94166. <xs:sequence>
  94167. <xs:element name="include" type="groupType"/>
  94168. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  94169. </xs:sequence>
  94170. <xs:sequence>
  94171. <xs:element name="exclude" type="groupType"/>
  94172. </xs:sequence>
  94173. </xs:choice>
  94174. </xs:complexType>
  94175. <xs:complexType name="groupType">
  94176. <xs:sequence>
  94177. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  94178. </xs:sequence>
  94179. </xs:complexType>
  94180. <xs:complexType name="extensionsType">
  94181. <xs:sequence>
  94182. <xs:element name="bootstrap" type="bootstrapType" maxOccurs="unbounded"/>
  94183. </xs:sequence>
  94184. </xs:complexType>
  94185. <xs:complexType name="bootstrapType">
  94186. <xs:sequence>
  94187. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  94188. </xs:sequence>
  94189. <xs:attribute name="class" type="xs:string" use="required"/>
  94190. </xs:complexType>
  94191. <xs:complexType name="parameterType">
  94192. <xs:attribute name="name" type="xs:string" use="required"/>
  94193. <xs:attribute name="value" type="xs:string" use="required"/>
  94194. </xs:complexType>
  94195. <xs:simpleType name="columnsType">
  94196. <xs:union>
  94197. <xs:simpleType>
  94198. <xs:restriction base="xs:integer"/>
  94199. </xs:simpleType>
  94200. <xs:simpleType>
  94201. <xs:restriction base="xs:string">
  94202. <xs:enumeration value="max"/>
  94203. </xs:restriction>
  94204. </xs:simpleType>
  94205. </xs:union>
  94206. </xs:simpleType>
  94207. <xs:group name="pathGroup">
  94208. <xs:sequence>
  94209. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94210. <xs:element name="directory" type="directoryFilterType"/>
  94211. <xs:element name="file" type="fileFilterType"/>
  94212. </xs:choice>
  94213. </xs:sequence>
  94214. </xs:group>
  94215. <xs:complexType name="directoryFilterType">
  94216. <xs:simpleContent>
  94217. <xs:extension base="xs:string">
  94218. <xs:attribute type="xs:string" name="prefix" default=""/>
  94219. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  94220. <xs:attributeGroup ref="phpVersionGroup"/>
  94221. </xs:extension>
  94222. </xs:simpleContent>
  94223. </xs:complexType>
  94224. <xs:simpleType name="executionOrderType">
  94225. <xs:restriction base="xs:string">
  94226. <xs:enumeration value="default"/>
  94227. <xs:enumeration value="defects"/>
  94228. <xs:enumeration value="depends"/>
  94229. <xs:enumeration value="depends,defects"/>
  94230. <xs:enumeration value="depends,duration"/>
  94231. <xs:enumeration value="depends,random"/>
  94232. <xs:enumeration value="depends,reverse"/>
  94233. <xs:enumeration value="depends,size"/>
  94234. <xs:enumeration value="duration"/>
  94235. <xs:enumeration value="no-depends"/>
  94236. <xs:enumeration value="no-depends,defects"/>
  94237. <xs:enumeration value="no-depends,duration"/>
  94238. <xs:enumeration value="no-depends,random"/>
  94239. <xs:enumeration value="no-depends,reverse"/>
  94240. <xs:enumeration value="no-depends,size"/>
  94241. <xs:enumeration value="random"/>
  94242. <xs:enumeration value="reverse"/>
  94243. <xs:enumeration value="size"/>
  94244. </xs:restriction>
  94245. </xs:simpleType>
  94246. <xs:complexType name="fileFilterType">
  94247. <xs:simpleContent>
  94248. <xs:extension base="xs:anyURI">
  94249. <xs:attributeGroup ref="phpVersionGroup"/>
  94250. </xs:extension>
  94251. </xs:simpleContent>
  94252. </xs:complexType>
  94253. <xs:attributeGroup name="phpVersionGroup">
  94254. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  94255. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  94256. </xs:attributeGroup>
  94257. <xs:complexType name="phpType">
  94258. <xs:sequence>
  94259. <xs:choice maxOccurs="unbounded">
  94260. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  94261. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94262. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94263. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94264. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94265. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94266. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94267. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94268. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94269. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94270. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94271. </xs:choice>
  94272. </xs:sequence>
  94273. </xs:complexType>
  94274. <xs:complexType name="namedValueType">
  94275. <xs:attribute name="name" use="required" type="xs:string"/>
  94276. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  94277. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  94278. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  94279. </xs:complexType>
  94280. <xs:complexType name="phpUnitType">
  94281. <xs:annotation>
  94282. <xs:documentation>The main type specifying the document structure</xs:documentation>
  94283. </xs:annotation>
  94284. <xs:group ref="configGroup"/>
  94285. <xs:attributeGroup ref="configAttributeGroup"/>
  94286. </xs:complexType>
  94287. <xs:attributeGroup name="configAttributeGroup">
  94288. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  94289. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  94290. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  94291. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94292. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  94293. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  94294. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  94295. <xs:attribute name="columns" type="columnsType" default="80"/>
  94296. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  94297. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  94298. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  94299. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  94300. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  94301. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  94302. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  94303. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  94304. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  94305. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  94306. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  94307. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  94308. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  94309. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  94310. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  94311. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  94312. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  94313. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  94314. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  94315. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  94316. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  94317. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  94318. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  94319. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  94320. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  94321. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  94322. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  94323. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  94324. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  94325. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  94326. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  94327. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  94328. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  94329. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  94330. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  94331. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  94332. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  94333. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  94334. </xs:attributeGroup>
  94335. <xs:group name="configGroup">
  94336. <xs:all>
  94337. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  94338. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  94339. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  94340. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  94341. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  94342. <xs:element name="php" type="phpType" minOccurs="0"/>
  94343. </xs:all>
  94344. </xs:group>
  94345. <xs:element name="testSuiteFacet" abstract="true"/>
  94346. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  94347. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  94348. <xs:complexType name="testSuitesType">
  94349. <xs:sequence>
  94350. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  94351. </xs:sequence>
  94352. </xs:complexType>
  94353. <xs:complexType name="testSuiteType">
  94354. <xs:sequence>
  94355. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94356. <xs:group ref="pathGroup"/>
  94357. <xs:element name="exclude" type="xs:string"/>
  94358. </xs:choice>
  94359. </xs:sequence>
  94360. <xs:attribute name="name" type="xs:string" use="required"/>
  94361. </xs:complexType>
  94362. <xs:group name="coverageReportGroup">
  94363. <xs:all>
  94364. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  94365. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  94366. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  94367. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  94368. <xs:element name="php" type="logToFileType" minOccurs="0" />
  94369. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  94370. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  94371. </xs:all>
  94372. </xs:group>
  94373. <xs:group name="loggingGroup">
  94374. <xs:all>
  94375. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  94376. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  94377. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  94378. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  94379. </xs:all>
  94380. </xs:group>
  94381. <xs:complexType name="logToFileType">
  94382. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94383. </xs:complexType>
  94384. <xs:complexType name="logToDirectoryType">
  94385. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  94386. </xs:complexType>
  94387. <xs:complexType name="coverageReportCrap4JType">
  94388. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94389. <xs:attribute name="threshold" type="xs:integer"/>
  94390. </xs:complexType>
  94391. <xs:complexType name="coverageReportHtmlType">
  94392. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  94393. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  94394. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  94395. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  94396. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  94397. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  94398. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  94399. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  94400. <xs:attribute name="customCssFile" type="xs:string"/>
  94401. </xs:complexType>
  94402. <xs:complexType name="coverageReportTextType">
  94403. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94404. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  94405. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  94406. </xs:complexType>
  94407. </xs:schema>
  94408. <?xml version="1.0" encoding="UTF-8"?>
  94409. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  94410. <xs:annotation>
  94411. <xs:documentation source="https://phpunit.de/documentation.html">
  94412. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.1 may be structured.
  94413. </xs:documentation>
  94414. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  94415. </xs:annotation>
  94416. <xs:element name="phpunit" type="phpUnitType">
  94417. <xs:annotation>
  94418. <xs:documentation>Root Element</xs:documentation>
  94419. </xs:annotation>
  94420. </xs:element>
  94421. <xs:complexType name="sourceType">
  94422. <xs:all>
  94423. <xs:element name="include" minOccurs="0" maxOccurs="1">
  94424. <xs:complexType>
  94425. <xs:group ref="sourcePathGroup"/>
  94426. </xs:complexType>
  94427. </xs:element>
  94428. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  94429. <xs:complexType>
  94430. <xs:group ref="sourcePathGroup"/>
  94431. </xs:complexType>
  94432. </xs:element>
  94433. </xs:all>
  94434. <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
  94435. <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
  94436. <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
  94437. </xs:complexType>
  94438. <xs:group name="sourcePathGroup">
  94439. <xs:sequence>
  94440. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94441. <xs:element name="directory" type="sourceDirectoryType"/>
  94442. <xs:element name="file" type="xs:anyURI"/>
  94443. </xs:choice>
  94444. </xs:sequence>
  94445. </xs:group>
  94446. <xs:complexType name="sourceDirectoryType">
  94447. <xs:simpleContent>
  94448. <xs:extension base="xs:string">
  94449. <xs:attribute type="xs:string" name="prefix" default=""/>
  94450. <xs:attribute type="xs:string" name="suffix" default=".php"/>
  94451. </xs:extension>
  94452. </xs:simpleContent>
  94453. </xs:complexType>
  94454. <xs:complexType name="coverageType">
  94455. <xs:all>
  94456. <xs:element name="report" minOccurs="0" maxOccurs="1">
  94457. <xs:complexType>
  94458. <xs:group ref="coverageReportGroup"/>
  94459. </xs:complexType>
  94460. </xs:element>
  94461. </xs:all>
  94462. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94463. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  94464. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  94465. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  94466. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  94467. </xs:complexType>
  94468. <xs:complexType name="loggingType">
  94469. <xs:group ref="loggingGroup"/>
  94470. </xs:complexType>
  94471. <xs:complexType name="groupsType">
  94472. <xs:choice>
  94473. <xs:sequence>
  94474. <xs:element name="include" type="groupType"/>
  94475. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  94476. </xs:sequence>
  94477. <xs:sequence>
  94478. <xs:element name="exclude" type="groupType"/>
  94479. </xs:sequence>
  94480. </xs:choice>
  94481. </xs:complexType>
  94482. <xs:complexType name="groupType">
  94483. <xs:sequence>
  94484. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  94485. </xs:sequence>
  94486. </xs:complexType>
  94487. <xs:complexType name="extensionsType">
  94488. <xs:sequence>
  94489. <xs:element name="bootstrap" type="bootstrapType" maxOccurs="unbounded"/>
  94490. </xs:sequence>
  94491. </xs:complexType>
  94492. <xs:complexType name="bootstrapType">
  94493. <xs:sequence>
  94494. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  94495. </xs:sequence>
  94496. <xs:attribute name="class" type="xs:string" use="required"/>
  94497. </xs:complexType>
  94498. <xs:complexType name="parameterType">
  94499. <xs:attribute name="name" type="xs:string" use="required"/>
  94500. <xs:attribute name="value" type="xs:string" use="required"/>
  94501. </xs:complexType>
  94502. <xs:simpleType name="columnsType">
  94503. <xs:union>
  94504. <xs:simpleType>
  94505. <xs:restriction base="xs:integer"/>
  94506. </xs:simpleType>
  94507. <xs:simpleType>
  94508. <xs:restriction base="xs:string">
  94509. <xs:enumeration value="max"/>
  94510. </xs:restriction>
  94511. </xs:simpleType>
  94512. </xs:union>
  94513. </xs:simpleType>
  94514. <xs:simpleType name="executionOrderType">
  94515. <xs:restriction base="xs:string">
  94516. <xs:enumeration value="default"/>
  94517. <xs:enumeration value="defects"/>
  94518. <xs:enumeration value="depends"/>
  94519. <xs:enumeration value="depends,defects"/>
  94520. <xs:enumeration value="depends,duration"/>
  94521. <xs:enumeration value="depends,random"/>
  94522. <xs:enumeration value="depends,reverse"/>
  94523. <xs:enumeration value="depends,size"/>
  94524. <xs:enumeration value="duration"/>
  94525. <xs:enumeration value="no-depends"/>
  94526. <xs:enumeration value="no-depends,defects"/>
  94527. <xs:enumeration value="no-depends,duration"/>
  94528. <xs:enumeration value="no-depends,random"/>
  94529. <xs:enumeration value="no-depends,reverse"/>
  94530. <xs:enumeration value="no-depends,size"/>
  94531. <xs:enumeration value="random"/>
  94532. <xs:enumeration value="reverse"/>
  94533. <xs:enumeration value="size"/>
  94534. </xs:restriction>
  94535. </xs:simpleType>
  94536. <xs:complexType name="phpType">
  94537. <xs:sequence>
  94538. <xs:choice maxOccurs="unbounded">
  94539. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  94540. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94541. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94542. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94543. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94544. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94545. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94546. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94547. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94548. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94549. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94550. </xs:choice>
  94551. </xs:sequence>
  94552. </xs:complexType>
  94553. <xs:complexType name="namedValueType">
  94554. <xs:attribute name="name" use="required" type="xs:string"/>
  94555. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  94556. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  94557. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  94558. </xs:complexType>
  94559. <xs:complexType name="phpUnitType">
  94560. <xs:annotation>
  94561. <xs:documentation>The main type specifying the document structure</xs:documentation>
  94562. </xs:annotation>
  94563. <xs:group ref="configGroup"/>
  94564. <xs:attributeGroup ref="configAttributeGroup"/>
  94565. </xs:complexType>
  94566. <xs:attributeGroup name="configAttributeGroup">
  94567. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  94568. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  94569. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  94570. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94571. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  94572. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  94573. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  94574. <xs:attribute name="columns" type="columnsType" default="80"/>
  94575. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  94576. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  94577. <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
  94578. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  94579. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  94580. <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
  94581. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  94582. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  94583. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  94584. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  94585. <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
  94586. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  94587. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  94588. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  94589. <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
  94590. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  94591. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  94592. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  94593. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  94594. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  94595. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  94596. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  94597. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  94598. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  94599. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  94600. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  94601. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  94602. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  94603. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  94604. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  94605. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  94606. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  94607. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  94608. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  94609. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  94610. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  94611. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  94612. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  94613. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  94614. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  94615. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  94616. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  94617. </xs:attributeGroup>
  94618. <xs:group name="configGroup">
  94619. <xs:all>
  94620. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  94621. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  94622. <xs:element name="source" type="sourceType" minOccurs="0"/>
  94623. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  94624. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  94625. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  94626. <xs:element name="php" type="phpType" minOccurs="0"/>
  94627. </xs:all>
  94628. </xs:group>
  94629. <xs:element name="testSuiteFacet" abstract="true"/>
  94630. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  94631. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  94632. <xs:complexType name="testSuitesType">
  94633. <xs:sequence>
  94634. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  94635. </xs:sequence>
  94636. </xs:complexType>
  94637. <xs:complexType name="testSuiteType">
  94638. <xs:sequence>
  94639. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94640. <xs:group ref="testSuitePathGroup"/>
  94641. <xs:element name="exclude" type="xs:string"/>
  94642. </xs:choice>
  94643. </xs:sequence>
  94644. <xs:attribute name="name" type="xs:string" use="required"/>
  94645. </xs:complexType>
  94646. <xs:group name="testSuitePathGroup">
  94647. <xs:sequence>
  94648. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94649. <xs:element name="directory" type="testSuiteDirectoryType"/>
  94650. <xs:element name="file" type="testSuiteFileType"/>
  94651. </xs:choice>
  94652. </xs:sequence>
  94653. </xs:group>
  94654. <xs:complexType name="testSuiteDirectoryType">
  94655. <xs:simpleContent>
  94656. <xs:extension base="xs:string">
  94657. <xs:attribute type="xs:string" name="prefix" default=""/>
  94658. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  94659. <xs:attributeGroup ref="phpVersionGroup"/>
  94660. </xs:extension>
  94661. </xs:simpleContent>
  94662. </xs:complexType>
  94663. <xs:complexType name="testSuiteFileType">
  94664. <xs:simpleContent>
  94665. <xs:extension base="xs:anyURI">
  94666. <xs:attributeGroup ref="phpVersionGroup"/>
  94667. </xs:extension>
  94668. </xs:simpleContent>
  94669. </xs:complexType>
  94670. <xs:attributeGroup name="phpVersionGroup">
  94671. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  94672. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  94673. </xs:attributeGroup>
  94674. <xs:group name="coverageReportGroup">
  94675. <xs:all>
  94676. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  94677. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  94678. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  94679. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  94680. <xs:element name="php" type="logToFileType" minOccurs="0" />
  94681. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  94682. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  94683. </xs:all>
  94684. </xs:group>
  94685. <xs:group name="loggingGroup">
  94686. <xs:all>
  94687. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  94688. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  94689. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  94690. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  94691. </xs:all>
  94692. </xs:group>
  94693. <xs:complexType name="logToFileType">
  94694. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94695. </xs:complexType>
  94696. <xs:complexType name="logToDirectoryType">
  94697. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  94698. </xs:complexType>
  94699. <xs:complexType name="coverageReportCrap4JType">
  94700. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94701. <xs:attribute name="threshold" type="xs:integer"/>
  94702. </xs:complexType>
  94703. <xs:complexType name="coverageReportHtmlType">
  94704. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  94705. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  94706. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  94707. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  94708. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  94709. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  94710. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  94711. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  94712. <xs:attribute name="customCssFile" type="xs:string"/>
  94713. </xs:complexType>
  94714. <xs:complexType name="coverageReportTextType">
  94715. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  94716. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  94717. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  94718. </xs:complexType>
  94719. </xs:schema>
  94720. <?xml version="1.0" encoding="UTF-8"?>
  94721. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  94722. <xs:annotation>
  94723. <xs:documentation source="https://phpunit.de/documentation.html">
  94724. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.2 may be structured.
  94725. </xs:documentation>
  94726. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  94727. </xs:annotation>
  94728. <xs:element name="phpunit" type="phpUnitType">
  94729. <xs:annotation>
  94730. <xs:documentation>Root Element</xs:documentation>
  94731. </xs:annotation>
  94732. </xs:element>
  94733. <xs:complexType name="sourceType">
  94734. <xs:all>
  94735. <xs:element name="include" minOccurs="0" maxOccurs="1">
  94736. <xs:complexType>
  94737. <xs:group ref="sourcePathGroup"/>
  94738. </xs:complexType>
  94739. </xs:element>
  94740. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  94741. <xs:complexType>
  94742. <xs:group ref="sourcePathGroup"/>
  94743. </xs:complexType>
  94744. </xs:element>
  94745. </xs:all>
  94746. <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
  94747. <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
  94748. <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
  94749. <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
  94750. <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
  94751. <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
  94752. <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
  94753. <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
  94754. <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
  94755. <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
  94756. </xs:complexType>
  94757. <xs:group name="sourcePathGroup">
  94758. <xs:sequence>
  94759. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94760. <xs:element name="directory" type="sourceDirectoryType"/>
  94761. <xs:element name="file" type="xs:anyURI"/>
  94762. </xs:choice>
  94763. </xs:sequence>
  94764. </xs:group>
  94765. <xs:complexType name="sourceDirectoryType">
  94766. <xs:simpleContent>
  94767. <xs:extension base="xs:string">
  94768. <xs:attribute type="xs:string" name="prefix" default=""/>
  94769. <xs:attribute type="xs:string" name="suffix" default=".php"/>
  94770. </xs:extension>
  94771. </xs:simpleContent>
  94772. </xs:complexType>
  94773. <xs:complexType name="coverageType">
  94774. <xs:all>
  94775. <xs:element name="report" minOccurs="0" maxOccurs="1">
  94776. <xs:complexType>
  94777. <xs:group ref="coverageReportGroup"/>
  94778. </xs:complexType>
  94779. </xs:element>
  94780. </xs:all>
  94781. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94782. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  94783. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  94784. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  94785. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  94786. </xs:complexType>
  94787. <xs:complexType name="loggingType">
  94788. <xs:group ref="loggingGroup"/>
  94789. </xs:complexType>
  94790. <xs:complexType name="groupsType">
  94791. <xs:choice>
  94792. <xs:sequence>
  94793. <xs:element name="include" type="groupType"/>
  94794. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  94795. </xs:sequence>
  94796. <xs:sequence>
  94797. <xs:element name="exclude" type="groupType"/>
  94798. </xs:sequence>
  94799. </xs:choice>
  94800. </xs:complexType>
  94801. <xs:complexType name="groupType">
  94802. <xs:sequence>
  94803. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  94804. </xs:sequence>
  94805. </xs:complexType>
  94806. <xs:complexType name="extensionsType">
  94807. <xs:sequence>
  94808. <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
  94809. </xs:sequence>
  94810. </xs:complexType>
  94811. <xs:complexType name="bootstrapType">
  94812. <xs:sequence>
  94813. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  94814. </xs:sequence>
  94815. <xs:attribute name="class" type="xs:string" use="required"/>
  94816. </xs:complexType>
  94817. <xs:complexType name="parameterType">
  94818. <xs:attribute name="name" type="xs:string" use="required"/>
  94819. <xs:attribute name="value" type="xs:string" use="required"/>
  94820. </xs:complexType>
  94821. <xs:simpleType name="columnsType">
  94822. <xs:union>
  94823. <xs:simpleType>
  94824. <xs:restriction base="xs:integer"/>
  94825. </xs:simpleType>
  94826. <xs:simpleType>
  94827. <xs:restriction base="xs:string">
  94828. <xs:enumeration value="max"/>
  94829. </xs:restriction>
  94830. </xs:simpleType>
  94831. </xs:union>
  94832. </xs:simpleType>
  94833. <xs:simpleType name="executionOrderType">
  94834. <xs:restriction base="xs:string">
  94835. <xs:enumeration value="default"/>
  94836. <xs:enumeration value="defects"/>
  94837. <xs:enumeration value="depends"/>
  94838. <xs:enumeration value="depends,defects"/>
  94839. <xs:enumeration value="depends,duration"/>
  94840. <xs:enumeration value="depends,random"/>
  94841. <xs:enumeration value="depends,reverse"/>
  94842. <xs:enumeration value="depends,size"/>
  94843. <xs:enumeration value="duration"/>
  94844. <xs:enumeration value="no-depends"/>
  94845. <xs:enumeration value="no-depends,defects"/>
  94846. <xs:enumeration value="no-depends,duration"/>
  94847. <xs:enumeration value="no-depends,random"/>
  94848. <xs:enumeration value="no-depends,reverse"/>
  94849. <xs:enumeration value="no-depends,size"/>
  94850. <xs:enumeration value="random"/>
  94851. <xs:enumeration value="reverse"/>
  94852. <xs:enumeration value="size"/>
  94853. </xs:restriction>
  94854. </xs:simpleType>
  94855. <xs:complexType name="phpType">
  94856. <xs:sequence>
  94857. <xs:choice maxOccurs="unbounded">
  94858. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  94859. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94860. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94861. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94862. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94863. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94864. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94865. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94866. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94867. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94868. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  94869. </xs:choice>
  94870. </xs:sequence>
  94871. </xs:complexType>
  94872. <xs:complexType name="namedValueType">
  94873. <xs:attribute name="name" use="required" type="xs:string"/>
  94874. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  94875. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  94876. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  94877. </xs:complexType>
  94878. <xs:complexType name="phpUnitType">
  94879. <xs:annotation>
  94880. <xs:documentation>The main type specifying the document structure</xs:documentation>
  94881. </xs:annotation>
  94882. <xs:group ref="configGroup"/>
  94883. <xs:attributeGroup ref="configAttributeGroup"/>
  94884. </xs:complexType>
  94885. <xs:attributeGroup name="configAttributeGroup">
  94886. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  94887. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  94888. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  94889. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  94890. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  94891. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  94892. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  94893. <xs:attribute name="columns" type="columnsType" default="80"/>
  94894. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  94895. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  94896. <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
  94897. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  94898. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  94899. <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
  94900. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  94901. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  94902. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  94903. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  94904. <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
  94905. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  94906. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  94907. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  94908. <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
  94909. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  94910. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  94911. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  94912. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  94913. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  94914. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  94915. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  94916. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  94917. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  94918. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  94919. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  94920. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  94921. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  94922. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  94923. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  94924. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  94925. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  94926. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  94927. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  94928. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  94929. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  94930. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  94931. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  94932. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  94933. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  94934. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  94935. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  94936. </xs:attributeGroup>
  94937. <xs:group name="configGroup">
  94938. <xs:all>
  94939. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  94940. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  94941. <xs:element name="source" type="sourceType" minOccurs="0"/>
  94942. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  94943. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  94944. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  94945. <xs:element name="php" type="phpType" minOccurs="0"/>
  94946. </xs:all>
  94947. </xs:group>
  94948. <xs:element name="testSuiteFacet" abstract="true"/>
  94949. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  94950. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  94951. <xs:complexType name="testSuitesType">
  94952. <xs:sequence>
  94953. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  94954. </xs:sequence>
  94955. </xs:complexType>
  94956. <xs:complexType name="testSuiteType">
  94957. <xs:sequence>
  94958. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94959. <xs:group ref="testSuitePathGroup"/>
  94960. <xs:element name="exclude" type="xs:string"/>
  94961. </xs:choice>
  94962. </xs:sequence>
  94963. <xs:attribute name="name" type="xs:string" use="required"/>
  94964. </xs:complexType>
  94965. <xs:group name="testSuitePathGroup">
  94966. <xs:sequence>
  94967. <xs:choice minOccurs="0" maxOccurs="unbounded">
  94968. <xs:element name="directory" type="testSuiteDirectoryType"/>
  94969. <xs:element name="file" type="testSuiteFileType"/>
  94970. </xs:choice>
  94971. </xs:sequence>
  94972. </xs:group>
  94973. <xs:complexType name="testSuiteDirectoryType">
  94974. <xs:simpleContent>
  94975. <xs:extension base="xs:string">
  94976. <xs:attribute type="xs:string" name="prefix" default=""/>
  94977. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  94978. <xs:attributeGroup ref="phpVersionGroup"/>
  94979. </xs:extension>
  94980. </xs:simpleContent>
  94981. </xs:complexType>
  94982. <xs:complexType name="testSuiteFileType">
  94983. <xs:simpleContent>
  94984. <xs:extension base="xs:anyURI">
  94985. <xs:attributeGroup ref="phpVersionGroup"/>
  94986. </xs:extension>
  94987. </xs:simpleContent>
  94988. </xs:complexType>
  94989. <xs:attributeGroup name="phpVersionGroup">
  94990. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  94991. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  94992. </xs:attributeGroup>
  94993. <xs:group name="coverageReportGroup">
  94994. <xs:all>
  94995. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  94996. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  94997. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  94998. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  94999. <xs:element name="php" type="logToFileType" minOccurs="0" />
  95000. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  95001. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  95002. </xs:all>
  95003. </xs:group>
  95004. <xs:group name="loggingGroup">
  95005. <xs:all>
  95006. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  95007. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  95008. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  95009. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  95010. </xs:all>
  95011. </xs:group>
  95012. <xs:complexType name="logToFileType">
  95013. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95014. </xs:complexType>
  95015. <xs:complexType name="logToDirectoryType">
  95016. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95017. </xs:complexType>
  95018. <xs:complexType name="coverageReportCrap4JType">
  95019. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95020. <xs:attribute name="threshold" type="xs:integer"/>
  95021. </xs:complexType>
  95022. <xs:complexType name="coverageReportHtmlType">
  95023. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95024. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  95025. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  95026. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  95027. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  95028. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  95029. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  95030. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  95031. <xs:attribute name="customCssFile" type="xs:string"/>
  95032. </xs:complexType>
  95033. <xs:complexType name="coverageReportTextType">
  95034. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95035. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  95036. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  95037. </xs:complexType>
  95038. </xs:schema>
  95039. <?xml version="1.0" encoding="UTF-8"?>
  95040. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  95041. <xs:annotation>
  95042. <xs:documentation source="https://phpunit.de/documentation.html">
  95043. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.3 may be structured.
  95044. </xs:documentation>
  95045. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  95046. </xs:annotation>
  95047. <xs:element name="phpunit" type="phpUnitType">
  95048. <xs:annotation>
  95049. <xs:documentation>Root Element</xs:documentation>
  95050. </xs:annotation>
  95051. </xs:element>
  95052. <xs:complexType name="sourceType">
  95053. <xs:all>
  95054. <xs:element name="include" minOccurs="0" maxOccurs="1">
  95055. <xs:complexType>
  95056. <xs:group ref="sourcePathGroup"/>
  95057. </xs:complexType>
  95058. </xs:element>
  95059. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  95060. <xs:complexType>
  95061. <xs:group ref="sourcePathGroup"/>
  95062. </xs:complexType>
  95063. </xs:element>
  95064. </xs:all>
  95065. <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
  95066. <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
  95067. <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
  95068. <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
  95069. <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
  95070. <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
  95071. <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
  95072. <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
  95073. <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
  95074. <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
  95075. </xs:complexType>
  95076. <xs:group name="sourcePathGroup">
  95077. <xs:sequence>
  95078. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95079. <xs:element name="directory" type="sourceDirectoryType"/>
  95080. <xs:element name="file" type="xs:anyURI"/>
  95081. </xs:choice>
  95082. </xs:sequence>
  95083. </xs:group>
  95084. <xs:complexType name="sourceDirectoryType">
  95085. <xs:simpleContent>
  95086. <xs:extension base="xs:string">
  95087. <xs:attribute type="xs:string" name="prefix" default=""/>
  95088. <xs:attribute type="xs:string" name="suffix" default=".php"/>
  95089. </xs:extension>
  95090. </xs:simpleContent>
  95091. </xs:complexType>
  95092. <xs:complexType name="coverageType">
  95093. <xs:all>
  95094. <xs:element name="report" minOccurs="0" maxOccurs="1">
  95095. <xs:complexType>
  95096. <xs:group ref="coverageReportGroup"/>
  95097. </xs:complexType>
  95098. </xs:element>
  95099. </xs:all>
  95100. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  95101. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  95102. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  95103. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  95104. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  95105. </xs:complexType>
  95106. <xs:complexType name="loggingType">
  95107. <xs:group ref="loggingGroup"/>
  95108. </xs:complexType>
  95109. <xs:complexType name="groupsType">
  95110. <xs:choice>
  95111. <xs:sequence>
  95112. <xs:element name="include" type="groupType"/>
  95113. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  95114. </xs:sequence>
  95115. <xs:sequence>
  95116. <xs:element name="exclude" type="groupType"/>
  95117. </xs:sequence>
  95118. </xs:choice>
  95119. </xs:complexType>
  95120. <xs:complexType name="groupType">
  95121. <xs:sequence>
  95122. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  95123. </xs:sequence>
  95124. </xs:complexType>
  95125. <xs:complexType name="extensionsType">
  95126. <xs:sequence>
  95127. <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
  95128. </xs:sequence>
  95129. </xs:complexType>
  95130. <xs:complexType name="bootstrapType">
  95131. <xs:sequence>
  95132. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  95133. </xs:sequence>
  95134. <xs:attribute name="class" type="xs:string" use="required"/>
  95135. </xs:complexType>
  95136. <xs:complexType name="parameterType">
  95137. <xs:attribute name="name" type="xs:string" use="required"/>
  95138. <xs:attribute name="value" type="xs:string" use="required"/>
  95139. </xs:complexType>
  95140. <xs:simpleType name="columnsType">
  95141. <xs:union>
  95142. <xs:simpleType>
  95143. <xs:restriction base="xs:integer"/>
  95144. </xs:simpleType>
  95145. <xs:simpleType>
  95146. <xs:restriction base="xs:string">
  95147. <xs:enumeration value="max"/>
  95148. </xs:restriction>
  95149. </xs:simpleType>
  95150. </xs:union>
  95151. </xs:simpleType>
  95152. <xs:simpleType name="executionOrderType">
  95153. <xs:restriction base="xs:string">
  95154. <xs:enumeration value="default"/>
  95155. <xs:enumeration value="defects"/>
  95156. <xs:enumeration value="depends"/>
  95157. <xs:enumeration value="depends,defects"/>
  95158. <xs:enumeration value="depends,duration"/>
  95159. <xs:enumeration value="depends,random"/>
  95160. <xs:enumeration value="depends,reverse"/>
  95161. <xs:enumeration value="depends,size"/>
  95162. <xs:enumeration value="duration"/>
  95163. <xs:enumeration value="no-depends"/>
  95164. <xs:enumeration value="no-depends,defects"/>
  95165. <xs:enumeration value="no-depends,duration"/>
  95166. <xs:enumeration value="no-depends,random"/>
  95167. <xs:enumeration value="no-depends,reverse"/>
  95168. <xs:enumeration value="no-depends,size"/>
  95169. <xs:enumeration value="random"/>
  95170. <xs:enumeration value="reverse"/>
  95171. <xs:enumeration value="size"/>
  95172. </xs:restriction>
  95173. </xs:simpleType>
  95174. <xs:complexType name="phpType">
  95175. <xs:sequence>
  95176. <xs:choice maxOccurs="unbounded">
  95177. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  95178. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95179. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95180. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95181. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95182. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95183. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95184. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95185. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95186. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95187. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95188. </xs:choice>
  95189. </xs:sequence>
  95190. </xs:complexType>
  95191. <xs:complexType name="namedValueType">
  95192. <xs:attribute name="name" use="required" type="xs:string"/>
  95193. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  95194. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  95195. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  95196. </xs:complexType>
  95197. <xs:complexType name="phpUnitType">
  95198. <xs:annotation>
  95199. <xs:documentation>The main type specifying the document structure</xs:documentation>
  95200. </xs:annotation>
  95201. <xs:group ref="configGroup"/>
  95202. <xs:attributeGroup ref="configAttributeGroup"/>
  95203. </xs:complexType>
  95204. <xs:attributeGroup name="configAttributeGroup">
  95205. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  95206. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  95207. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  95208. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  95209. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  95210. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  95211. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  95212. <xs:attribute name="columns" type="columnsType" default="80"/>
  95213. <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
  95214. <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
  95215. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  95216. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  95217. <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
  95218. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  95219. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  95220. <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
  95221. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  95222. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  95223. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  95224. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  95225. <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
  95226. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  95227. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  95228. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  95229. <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
  95230. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  95231. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  95232. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  95233. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  95234. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  95235. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  95236. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  95237. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  95238. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  95239. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  95240. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  95241. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  95242. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  95243. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  95244. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  95245. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  95246. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  95247. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  95248. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  95249. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  95250. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  95251. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  95252. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  95253. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  95254. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  95255. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  95256. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  95257. </xs:attributeGroup>
  95258. <xs:group name="configGroup">
  95259. <xs:all>
  95260. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  95261. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  95262. <xs:element name="source" type="sourceType" minOccurs="0"/>
  95263. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  95264. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  95265. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  95266. <xs:element name="php" type="phpType" minOccurs="0"/>
  95267. </xs:all>
  95268. </xs:group>
  95269. <xs:element name="testSuiteFacet" abstract="true"/>
  95270. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  95271. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  95272. <xs:complexType name="testSuitesType">
  95273. <xs:sequence>
  95274. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  95275. </xs:sequence>
  95276. </xs:complexType>
  95277. <xs:complexType name="testSuiteType">
  95278. <xs:sequence>
  95279. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95280. <xs:group ref="testSuitePathGroup"/>
  95281. <xs:element name="exclude" type="xs:string"/>
  95282. </xs:choice>
  95283. </xs:sequence>
  95284. <xs:attribute name="name" type="xs:string" use="required"/>
  95285. </xs:complexType>
  95286. <xs:group name="testSuitePathGroup">
  95287. <xs:sequence>
  95288. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95289. <xs:element name="directory" type="testSuiteDirectoryType"/>
  95290. <xs:element name="file" type="testSuiteFileType"/>
  95291. </xs:choice>
  95292. </xs:sequence>
  95293. </xs:group>
  95294. <xs:complexType name="testSuiteDirectoryType">
  95295. <xs:simpleContent>
  95296. <xs:extension base="xs:string">
  95297. <xs:attribute type="xs:string" name="prefix" default=""/>
  95298. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  95299. <xs:attributeGroup ref="phpVersionGroup"/>
  95300. </xs:extension>
  95301. </xs:simpleContent>
  95302. </xs:complexType>
  95303. <xs:complexType name="testSuiteFileType">
  95304. <xs:simpleContent>
  95305. <xs:extension base="xs:anyURI">
  95306. <xs:attributeGroup ref="phpVersionGroup"/>
  95307. </xs:extension>
  95308. </xs:simpleContent>
  95309. </xs:complexType>
  95310. <xs:attributeGroup name="phpVersionGroup">
  95311. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  95312. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  95313. </xs:attributeGroup>
  95314. <xs:group name="coverageReportGroup">
  95315. <xs:all>
  95316. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  95317. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  95318. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  95319. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  95320. <xs:element name="php" type="logToFileType" minOccurs="0" />
  95321. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  95322. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  95323. </xs:all>
  95324. </xs:group>
  95325. <xs:group name="loggingGroup">
  95326. <xs:all>
  95327. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  95328. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  95329. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  95330. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  95331. </xs:all>
  95332. </xs:group>
  95333. <xs:complexType name="logToFileType">
  95334. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95335. </xs:complexType>
  95336. <xs:complexType name="logToDirectoryType">
  95337. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95338. </xs:complexType>
  95339. <xs:complexType name="coverageReportCrap4JType">
  95340. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95341. <xs:attribute name="threshold" type="xs:integer"/>
  95342. </xs:complexType>
  95343. <xs:complexType name="coverageReportHtmlType">
  95344. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95345. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  95346. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  95347. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  95348. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  95349. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  95350. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  95351. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  95352. <xs:attribute name="customCssFile" type="xs:string"/>
  95353. </xs:complexType>
  95354. <xs:complexType name="coverageReportTextType">
  95355. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95356. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  95357. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  95358. </xs:complexType>
  95359. </xs:schema>
  95360. <?xml version="1.0" encoding="UTF-8"?>
  95361. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  95362. <xs:annotation>
  95363. <xs:documentation source="https://phpunit.de/documentation.html">
  95364. This Schema file defines the rules by which the XML configuration file of PHPUnit 10.4 may be structured.
  95365. </xs:documentation>
  95366. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  95367. </xs:annotation>
  95368. <xs:element name="phpunit" type="phpUnitType">
  95369. <xs:annotation>
  95370. <xs:documentation>Root Element</xs:documentation>
  95371. </xs:annotation>
  95372. </xs:element>
  95373. <xs:complexType name="sourceType">
  95374. <xs:all>
  95375. <xs:element name="include" minOccurs="0" maxOccurs="1">
  95376. <xs:complexType>
  95377. <xs:group ref="sourcePathGroup"/>
  95378. </xs:complexType>
  95379. </xs:element>
  95380. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  95381. <xs:complexType>
  95382. <xs:group ref="sourcePathGroup"/>
  95383. </xs:complexType>
  95384. </xs:element>
  95385. </xs:all>
  95386. <xs:attribute name="baseline" type="xs:anyURI"/>
  95387. <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
  95388. <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
  95389. <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
  95390. <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
  95391. <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
  95392. <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
  95393. <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
  95394. <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
  95395. <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
  95396. <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
  95397. </xs:complexType>
  95398. <xs:group name="sourcePathGroup">
  95399. <xs:sequence>
  95400. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95401. <xs:element name="directory" type="sourceDirectoryType"/>
  95402. <xs:element name="file" type="xs:anyURI"/>
  95403. </xs:choice>
  95404. </xs:sequence>
  95405. </xs:group>
  95406. <xs:complexType name="sourceDirectoryType">
  95407. <xs:simpleContent>
  95408. <xs:extension base="xs:string">
  95409. <xs:attribute type="xs:string" name="prefix" default=""/>
  95410. <xs:attribute type="xs:string" name="suffix" default=".php"/>
  95411. </xs:extension>
  95412. </xs:simpleContent>
  95413. </xs:complexType>
  95414. <xs:complexType name="coverageType">
  95415. <xs:all>
  95416. <xs:element name="report" minOccurs="0" maxOccurs="1">
  95417. <xs:complexType>
  95418. <xs:group ref="coverageReportGroup"/>
  95419. </xs:complexType>
  95420. </xs:element>
  95421. </xs:all>
  95422. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  95423. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  95424. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  95425. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  95426. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  95427. </xs:complexType>
  95428. <xs:complexType name="loggingType">
  95429. <xs:group ref="loggingGroup"/>
  95430. </xs:complexType>
  95431. <xs:complexType name="groupsType">
  95432. <xs:choice>
  95433. <xs:sequence>
  95434. <xs:element name="include" type="groupType"/>
  95435. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  95436. </xs:sequence>
  95437. <xs:sequence>
  95438. <xs:element name="exclude" type="groupType"/>
  95439. </xs:sequence>
  95440. </xs:choice>
  95441. </xs:complexType>
  95442. <xs:complexType name="groupType">
  95443. <xs:sequence>
  95444. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  95445. </xs:sequence>
  95446. </xs:complexType>
  95447. <xs:complexType name="extensionsType">
  95448. <xs:sequence>
  95449. <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
  95450. </xs:sequence>
  95451. </xs:complexType>
  95452. <xs:complexType name="bootstrapType">
  95453. <xs:sequence>
  95454. <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
  95455. </xs:sequence>
  95456. <xs:attribute name="class" type="xs:string" use="required"/>
  95457. </xs:complexType>
  95458. <xs:complexType name="parameterType">
  95459. <xs:attribute name="name" type="xs:string" use="required"/>
  95460. <xs:attribute name="value" type="xs:string" use="required"/>
  95461. </xs:complexType>
  95462. <xs:simpleType name="columnsType">
  95463. <xs:union>
  95464. <xs:simpleType>
  95465. <xs:restriction base="xs:integer"/>
  95466. </xs:simpleType>
  95467. <xs:simpleType>
  95468. <xs:restriction base="xs:string">
  95469. <xs:enumeration value="max"/>
  95470. </xs:restriction>
  95471. </xs:simpleType>
  95472. </xs:union>
  95473. </xs:simpleType>
  95474. <xs:simpleType name="executionOrderType">
  95475. <xs:restriction base="xs:string">
  95476. <xs:enumeration value="default"/>
  95477. <xs:enumeration value="defects"/>
  95478. <xs:enumeration value="depends"/>
  95479. <xs:enumeration value="depends,defects"/>
  95480. <xs:enumeration value="depends,duration"/>
  95481. <xs:enumeration value="depends,random"/>
  95482. <xs:enumeration value="depends,reverse"/>
  95483. <xs:enumeration value="depends,size"/>
  95484. <xs:enumeration value="duration"/>
  95485. <xs:enumeration value="no-depends"/>
  95486. <xs:enumeration value="no-depends,defects"/>
  95487. <xs:enumeration value="no-depends,duration"/>
  95488. <xs:enumeration value="no-depends,random"/>
  95489. <xs:enumeration value="no-depends,reverse"/>
  95490. <xs:enumeration value="no-depends,size"/>
  95491. <xs:enumeration value="random"/>
  95492. <xs:enumeration value="reverse"/>
  95493. <xs:enumeration value="size"/>
  95494. </xs:restriction>
  95495. </xs:simpleType>
  95496. <xs:complexType name="phpType">
  95497. <xs:sequence>
  95498. <xs:choice maxOccurs="unbounded">
  95499. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  95500. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95501. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95502. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95503. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95504. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95505. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95506. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95507. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95508. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95509. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95510. </xs:choice>
  95511. </xs:sequence>
  95512. </xs:complexType>
  95513. <xs:complexType name="namedValueType">
  95514. <xs:attribute name="name" use="required" type="xs:string"/>
  95515. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  95516. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  95517. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  95518. </xs:complexType>
  95519. <xs:complexType name="phpUnitType">
  95520. <xs:annotation>
  95521. <xs:documentation>The main type specifying the document structure</xs:documentation>
  95522. </xs:annotation>
  95523. <xs:group ref="configGroup"/>
  95524. <xs:attributeGroup ref="configAttributeGroup"/>
  95525. </xs:complexType>
  95526. <xs:attributeGroup name="configAttributeGroup">
  95527. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  95528. <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
  95529. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  95530. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  95531. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  95532. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  95533. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  95534. <xs:attribute name="columns" type="columnsType" default="80"/>
  95535. <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
  95536. <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
  95537. <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
  95538. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  95539. <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
  95540. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  95541. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  95542. <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
  95543. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  95544. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  95545. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  95546. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  95547. <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
  95548. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  95549. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  95550. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  95551. <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
  95552. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  95553. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  95554. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  95555. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  95556. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  95557. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  95558. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  95559. <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
  95560. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  95561. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  95562. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  95563. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  95564. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  95565. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  95566. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  95567. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  95568. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  95569. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  95570. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  95571. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  95572. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  95573. <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
  95574. <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
  95575. <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
  95576. <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
  95577. <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
  95578. <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
  95579. </xs:attributeGroup>
  95580. <xs:group name="configGroup">
  95581. <xs:all>
  95582. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  95583. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  95584. <xs:element name="source" type="sourceType" minOccurs="0"/>
  95585. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  95586. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  95587. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  95588. <xs:element name="php" type="phpType" minOccurs="0"/>
  95589. </xs:all>
  95590. </xs:group>
  95591. <xs:element name="testSuiteFacet" abstract="true"/>
  95592. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  95593. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  95594. <xs:complexType name="testSuitesType">
  95595. <xs:sequence>
  95596. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  95597. </xs:sequence>
  95598. </xs:complexType>
  95599. <xs:complexType name="testSuiteType">
  95600. <xs:sequence>
  95601. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95602. <xs:group ref="testSuitePathGroup"/>
  95603. <xs:element name="exclude" type="xs:string"/>
  95604. </xs:choice>
  95605. </xs:sequence>
  95606. <xs:attribute name="name" type="xs:string" use="required"/>
  95607. </xs:complexType>
  95608. <xs:group name="testSuitePathGroup">
  95609. <xs:sequence>
  95610. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95611. <xs:element name="directory" type="testSuiteDirectoryType"/>
  95612. <xs:element name="file" type="testSuiteFileType"/>
  95613. </xs:choice>
  95614. </xs:sequence>
  95615. </xs:group>
  95616. <xs:complexType name="testSuiteDirectoryType">
  95617. <xs:simpleContent>
  95618. <xs:extension base="xs:string">
  95619. <xs:attribute type="xs:string" name="prefix" default=""/>
  95620. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  95621. <xs:attributeGroup ref="phpVersionGroup"/>
  95622. </xs:extension>
  95623. </xs:simpleContent>
  95624. </xs:complexType>
  95625. <xs:complexType name="testSuiteFileType">
  95626. <xs:simpleContent>
  95627. <xs:extension base="xs:anyURI">
  95628. <xs:attributeGroup ref="phpVersionGroup"/>
  95629. </xs:extension>
  95630. </xs:simpleContent>
  95631. </xs:complexType>
  95632. <xs:attributeGroup name="phpVersionGroup">
  95633. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  95634. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  95635. </xs:attributeGroup>
  95636. <xs:group name="coverageReportGroup">
  95637. <xs:all>
  95638. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  95639. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  95640. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  95641. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  95642. <xs:element name="php" type="logToFileType" minOccurs="0" />
  95643. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  95644. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  95645. </xs:all>
  95646. </xs:group>
  95647. <xs:group name="loggingGroup">
  95648. <xs:all>
  95649. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  95650. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  95651. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  95652. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  95653. </xs:all>
  95654. </xs:group>
  95655. <xs:complexType name="logToFileType">
  95656. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95657. </xs:complexType>
  95658. <xs:complexType name="logToDirectoryType">
  95659. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95660. </xs:complexType>
  95661. <xs:complexType name="coverageReportCrap4JType">
  95662. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95663. <xs:attribute name="threshold" type="xs:integer"/>
  95664. </xs:complexType>
  95665. <xs:complexType name="coverageReportHtmlType">
  95666. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  95667. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  95668. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  95669. <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
  95670. <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
  95671. <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
  95672. <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
  95673. <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
  95674. <xs:attribute name="customCssFile" type="xs:string"/>
  95675. </xs:complexType>
  95676. <xs:complexType name="coverageReportTextType">
  95677. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  95678. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  95679. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  95680. </xs:complexType>
  95681. </xs:schema>
  95682. <?xml version="1.0" encoding="UTF-8"?>
  95683. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  95684. <xs:annotation>
  95685. <xs:documentation source="https://phpunit.de/documentation.html">
  95686. This Schema file defines the rules by which the XML configuration file of PHPUnit 8.5 may be structured.
  95687. </xs:documentation>
  95688. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  95689. </xs:annotation>
  95690. <xs:element name="phpunit" type="phpUnitType">
  95691. <xs:annotation>
  95692. <xs:documentation>Root Element</xs:documentation>
  95693. </xs:annotation>
  95694. </xs:element>
  95695. <xs:complexType name="filtersType">
  95696. <xs:sequence>
  95697. <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
  95698. </xs:sequence>
  95699. </xs:complexType>
  95700. <xs:complexType name="filterType">
  95701. <xs:sequence>
  95702. <xs:choice maxOccurs="unbounded" minOccurs="0">
  95703. <xs:group ref="pathGroup"/>
  95704. <xs:element name="exclude">
  95705. <xs:complexType>
  95706. <xs:group ref="pathGroup"/>
  95707. </xs:complexType>
  95708. </xs:element>
  95709. </xs:choice>
  95710. </xs:sequence>
  95711. </xs:complexType>
  95712. <xs:complexType name="whiteListType">
  95713. <xs:complexContent>
  95714. <xs:extension base="filterType">
  95715. <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
  95716. <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
  95717. </xs:extension>
  95718. </xs:complexContent>
  95719. </xs:complexType>
  95720. <xs:complexType name="groupsType">
  95721. <xs:choice>
  95722. <xs:sequence>
  95723. <xs:element name="include" type="groupType"/>
  95724. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  95725. </xs:sequence>
  95726. <xs:sequence>
  95727. <xs:element name="exclude" type="groupType"/>
  95728. </xs:sequence>
  95729. </xs:choice>
  95730. </xs:complexType>
  95731. <xs:complexType name="groupType">
  95732. <xs:sequence>
  95733. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  95734. </xs:sequence>
  95735. </xs:complexType>
  95736. <xs:complexType name="extensionsType">
  95737. <xs:sequence>
  95738. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  95739. </xs:sequence>
  95740. </xs:complexType>
  95741. <xs:complexType name="listenersType">
  95742. <xs:sequence>
  95743. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  95744. </xs:sequence>
  95745. </xs:complexType>
  95746. <xs:complexType name="objectType">
  95747. <xs:sequence>
  95748. <xs:element name="arguments" minOccurs="0">
  95749. <xs:complexType>
  95750. <xs:group ref="argumentsGroup"/>
  95751. </xs:complexType>
  95752. </xs:element>
  95753. </xs:sequence>
  95754. <xs:attribute name="class" type="xs:string" use="required"/>
  95755. <xs:attribute name="file" type="xs:anyURI"/>
  95756. </xs:complexType>
  95757. <xs:complexType name="arrayType">
  95758. <xs:sequence>
  95759. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  95760. </xs:sequence>
  95761. </xs:complexType>
  95762. <xs:complexType name="argumentType">
  95763. <xs:group ref="argumentChoice"/>
  95764. <xs:attribute name="key" use="required"/>
  95765. </xs:complexType>
  95766. <xs:group name="argumentsGroup">
  95767. <xs:sequence>
  95768. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95769. <xs:element name="array" type="arrayType" />
  95770. <xs:element name="integer" type="xs:integer" />
  95771. <xs:element name="string" type="xs:string" />
  95772. <xs:element name="double" type="xs:double" />
  95773. <xs:element name="null" />
  95774. <xs:element name="object" type="objectType" />
  95775. <xs:element name="file" type="xs:anyURI" />
  95776. <xs:element name="directory" type="xs:anyURI" />
  95777. <xs:element name="boolean" type="xs:boolean" />
  95778. </xs:choice>
  95779. </xs:sequence>
  95780. </xs:group>
  95781. <xs:group name="argumentChoice">
  95782. <xs:choice>
  95783. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  95784. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  95785. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  95786. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  95787. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  95788. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  95789. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  95790. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  95791. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  95792. </xs:choice>
  95793. </xs:group>
  95794. <xs:simpleType name="columnsType">
  95795. <xs:union>
  95796. <xs:simpleType>
  95797. <xs:restriction base="xs:integer"/>
  95798. </xs:simpleType>
  95799. <xs:simpleType>
  95800. <xs:restriction base="xs:string">
  95801. <xs:enumeration value="max"/>
  95802. </xs:restriction>
  95803. </xs:simpleType>
  95804. </xs:union>
  95805. </xs:simpleType>
  95806. <xs:complexType name="loggersType">
  95807. <xs:sequence>
  95808. <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
  95809. </xs:sequence>
  95810. </xs:complexType>
  95811. <xs:complexType name="loggerType">
  95812. <xs:attribute name="type">
  95813. <xs:simpleType>
  95814. <xs:restriction base="xs:string">
  95815. <xs:enumeration value="coverage-html"/>
  95816. <xs:enumeration value="coverage-text"/>
  95817. <xs:enumeration value="coverage-clover"/>
  95818. <xs:enumeration value="coverage-crap4j"/>
  95819. <xs:enumeration value="coverage-xml"/>
  95820. <xs:enumeration value="coverage-php"/>
  95821. <xs:enumeration value="json"/>
  95822. <xs:enumeration value="plain"/>
  95823. <xs:enumeration value="tap"/>
  95824. <xs:enumeration value="teamcity"/>
  95825. <xs:enumeration value="junit"/>
  95826. <xs:enumeration value="testdox-html"/>
  95827. <xs:enumeration value="testdox-text"/>
  95828. <xs:enumeration value="testdox-xml"/>
  95829. </xs:restriction>
  95830. </xs:simpleType>
  95831. </xs:attribute>
  95832. <xs:attribute name="target" type="xs:anyURI"/>
  95833. <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="50"/>
  95834. <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="90"/>
  95835. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  95836. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  95837. <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
  95838. </xs:complexType>
  95839. <xs:group name="pathGroup">
  95840. <xs:sequence>
  95841. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95842. <xs:element name="directory" type="directoryFilterType"/>
  95843. <xs:element name="file" type="fileFilterType"/>
  95844. </xs:choice>
  95845. </xs:sequence>
  95846. </xs:group>
  95847. <xs:complexType name="directoryFilterType">
  95848. <xs:simpleContent>
  95849. <xs:extension base="xs:string">
  95850. <xs:attribute type="xs:string" name="prefix" default=""/>
  95851. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  95852. <xs:attributeGroup ref="phpVersionGroup"/>
  95853. </xs:extension>
  95854. </xs:simpleContent>
  95855. </xs:complexType>
  95856. <xs:simpleType name="executionOrderType">
  95857. <xs:restriction base="xs:string">
  95858. <xs:enumeration value="default"/>
  95859. <xs:enumeration value="defects"/>
  95860. <xs:enumeration value="depends"/>
  95861. <xs:enumeration value="depends,defects"/>
  95862. <xs:enumeration value="depends,duration"/>
  95863. <xs:enumeration value="depends,random"/>
  95864. <xs:enumeration value="depends,reverse"/>
  95865. <xs:enumeration value="depends,size"/>
  95866. <xs:enumeration value="duration"/>
  95867. <xs:enumeration value="no-depends"/>
  95868. <xs:enumeration value="no-depends,defects"/>
  95869. <xs:enumeration value="no-depends,duration"/>
  95870. <xs:enumeration value="no-depends,random"/>
  95871. <xs:enumeration value="no-depends,reverse"/>
  95872. <xs:enumeration value="no-depends,size"/>
  95873. <xs:enumeration value="random"/>
  95874. <xs:enumeration value="reverse"/>
  95875. <xs:enumeration value="size"/>
  95876. </xs:restriction>
  95877. </xs:simpleType>
  95878. <xs:complexType name="fileFilterType">
  95879. <xs:simpleContent>
  95880. <xs:extension base="xs:anyURI">
  95881. <xs:attributeGroup ref="phpVersionGroup"/>
  95882. </xs:extension>
  95883. </xs:simpleContent>
  95884. </xs:complexType>
  95885. <xs:attributeGroup name="phpVersionGroup">
  95886. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  95887. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  95888. </xs:attributeGroup>
  95889. <xs:complexType name="phpType">
  95890. <xs:sequence>
  95891. <xs:choice maxOccurs="unbounded">
  95892. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  95893. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95894. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95895. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95896. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95897. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95898. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95899. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95900. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95901. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95902. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  95903. </xs:choice>
  95904. </xs:sequence>
  95905. </xs:complexType>
  95906. <xs:complexType name="namedValueType">
  95907. <xs:attribute name="name" use="required" type="xs:string"/>
  95908. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  95909. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  95910. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  95911. </xs:complexType>
  95912. <xs:complexType name="phpUnitType">
  95913. <xs:annotation>
  95914. <xs:documentation>The main type specifying the document structure</xs:documentation>
  95915. </xs:annotation>
  95916. <xs:group ref="configGroup"/>
  95917. <xs:attributeGroup ref="configAttributeGroup"/>
  95918. </xs:complexType>
  95919. <xs:attributeGroup name="configAttributeGroup">
  95920. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  95921. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  95922. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  95923. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  95924. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  95925. <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
  95926. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  95927. <xs:attribute name="columns" type="columnsType" default="80"/>
  95928. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="false"/>
  95929. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  95930. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  95931. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  95932. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  95933. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  95934. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
  95935. <xs:attribute name="printerFile" type="xs:anyURI"/>
  95936. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  95937. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  95938. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  95939. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  95940. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  95941. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  95942. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  95943. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  95944. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  95945. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  95946. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  95947. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  95948. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  95949. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  95950. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  95951. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  95952. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  95953. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  95954. <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
  95955. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  95956. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  95957. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  95958. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  95959. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  95960. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  95961. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  95962. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  95963. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  95964. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  95965. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  95966. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  95967. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  95968. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  95969. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  95970. </xs:attributeGroup>
  95971. <xs:group name="configGroup">
  95972. <xs:all>
  95973. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  95974. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  95975. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  95976. <xs:element name="filter" type="filtersType" minOccurs="0"/>
  95977. <xs:element name="logging" type="loggersType" minOccurs="0"/>
  95978. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  95979. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  95980. <xs:element name="php" type="phpType" minOccurs="0"/>
  95981. </xs:all>
  95982. </xs:group>
  95983. <xs:element name="testSuiteFacet" abstract="true"/>
  95984. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  95985. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  95986. <xs:complexType name="testSuitesType">
  95987. <xs:sequence>
  95988. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  95989. </xs:sequence>
  95990. </xs:complexType>
  95991. <xs:complexType name="testSuiteType">
  95992. <xs:sequence>
  95993. <xs:choice minOccurs="0" maxOccurs="unbounded">
  95994. <xs:group ref="pathGroup"/>
  95995. <xs:element name="exclude" type="xs:string"/>
  95996. </xs:choice>
  95997. </xs:sequence>
  95998. <xs:attribute name="name" type="xs:string" use="required"/>
  95999. </xs:complexType>
  96000. </xs:schema>
  96001. <?xml version="1.0" encoding="UTF-8"?>
  96002. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  96003. <xs:annotation>
  96004. <xs:documentation source="https://phpunit.de/documentation.html">
  96005. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured.
  96006. </xs:documentation>
  96007. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  96008. </xs:annotation>
  96009. <xs:element name="phpunit" type="phpUnitType">
  96010. <xs:annotation>
  96011. <xs:documentation>Root Element</xs:documentation>
  96012. </xs:annotation>
  96013. </xs:element>
  96014. <xs:complexType name="filtersType">
  96015. <xs:sequence>
  96016. <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
  96017. </xs:sequence>
  96018. </xs:complexType>
  96019. <xs:complexType name="filterType">
  96020. <xs:sequence>
  96021. <xs:choice maxOccurs="unbounded" minOccurs="0">
  96022. <xs:group ref="pathGroup"/>
  96023. <xs:element name="exclude">
  96024. <xs:complexType>
  96025. <xs:group ref="pathGroup"/>
  96026. </xs:complexType>
  96027. </xs:element>
  96028. </xs:choice>
  96029. </xs:sequence>
  96030. </xs:complexType>
  96031. <xs:complexType name="whiteListType">
  96032. <xs:complexContent>
  96033. <xs:extension base="filterType">
  96034. <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
  96035. <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
  96036. </xs:extension>
  96037. </xs:complexContent>
  96038. </xs:complexType>
  96039. <xs:complexType name="groupsType">
  96040. <xs:choice>
  96041. <xs:sequence>
  96042. <xs:element name="include" type="groupType"/>
  96043. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  96044. </xs:sequence>
  96045. <xs:sequence>
  96046. <xs:element name="exclude" type="groupType"/>
  96047. </xs:sequence>
  96048. </xs:choice>
  96049. </xs:complexType>
  96050. <xs:complexType name="groupType">
  96051. <xs:sequence>
  96052. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  96053. </xs:sequence>
  96054. </xs:complexType>
  96055. <xs:complexType name="extensionsType">
  96056. <xs:sequence>
  96057. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  96058. </xs:sequence>
  96059. </xs:complexType>
  96060. <xs:complexType name="listenersType">
  96061. <xs:sequence>
  96062. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  96063. </xs:sequence>
  96064. </xs:complexType>
  96065. <xs:complexType name="objectType">
  96066. <xs:sequence>
  96067. <xs:element name="arguments" minOccurs="0">
  96068. <xs:complexType>
  96069. <xs:group ref="argumentsGroup"/>
  96070. </xs:complexType>
  96071. </xs:element>
  96072. </xs:sequence>
  96073. <xs:attribute name="class" type="xs:string" use="required"/>
  96074. <xs:attribute name="file" type="xs:anyURI"/>
  96075. </xs:complexType>
  96076. <xs:complexType name="arrayType">
  96077. <xs:sequence>
  96078. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  96079. </xs:sequence>
  96080. </xs:complexType>
  96081. <xs:complexType name="argumentType">
  96082. <xs:group ref="argumentChoice"/>
  96083. <xs:attribute name="key" use="required"/>
  96084. </xs:complexType>
  96085. <xs:group name="argumentsGroup">
  96086. <xs:sequence>
  96087. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96088. <xs:element name="array" type="arrayType" />
  96089. <xs:element name="integer" type="xs:integer" />
  96090. <xs:element name="string" type="xs:string" />
  96091. <xs:element name="double" type="xs:double" />
  96092. <xs:element name="null" />
  96093. <xs:element name="object" type="objectType" />
  96094. <xs:element name="file" type="xs:anyURI" />
  96095. <xs:element name="directory" type="xs:anyURI" />
  96096. <xs:element name="boolean" type="xs:boolean" />
  96097. </xs:choice>
  96098. </xs:sequence>
  96099. </xs:group>
  96100. <xs:group name="argumentChoice">
  96101. <xs:choice>
  96102. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  96103. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  96104. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  96105. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  96106. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  96107. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  96108. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96109. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96110. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  96111. </xs:choice>
  96112. </xs:group>
  96113. <xs:simpleType name="columnsType">
  96114. <xs:union>
  96115. <xs:simpleType>
  96116. <xs:restriction base="xs:integer"/>
  96117. </xs:simpleType>
  96118. <xs:simpleType>
  96119. <xs:restriction base="xs:string">
  96120. <xs:enumeration value="max"/>
  96121. </xs:restriction>
  96122. </xs:simpleType>
  96123. </xs:union>
  96124. </xs:simpleType>
  96125. <xs:complexType name="loggersType">
  96126. <xs:sequence>
  96127. <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
  96128. </xs:sequence>
  96129. </xs:complexType>
  96130. <xs:complexType name="loggerType">
  96131. <xs:attribute name="type">
  96132. <xs:simpleType>
  96133. <xs:restriction base="xs:string">
  96134. <xs:enumeration value="coverage-html"/>
  96135. <xs:enumeration value="coverage-text"/>
  96136. <xs:enumeration value="coverage-clover"/>
  96137. <xs:enumeration value="coverage-crap4j"/>
  96138. <xs:enumeration value="coverage-xml"/>
  96139. <xs:enumeration value="coverage-php"/>
  96140. <xs:enumeration value="plain"/>
  96141. <xs:enumeration value="teamcity"/>
  96142. <xs:enumeration value="junit"/>
  96143. <xs:enumeration value="testdox-html"/>
  96144. <xs:enumeration value="testdox-text"/>
  96145. <xs:enumeration value="testdox-xml"/>
  96146. </xs:restriction>
  96147. </xs:simpleType>
  96148. </xs:attribute>
  96149. <xs:attribute name="target" type="xs:anyURI"/>
  96150. <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="35"/>
  96151. <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="70"/>
  96152. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  96153. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  96154. <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
  96155. </xs:complexType>
  96156. <xs:group name="pathGroup">
  96157. <xs:sequence>
  96158. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96159. <xs:element name="directory" type="directoryFilterType"/>
  96160. <xs:element name="file" type="fileFilterType"/>
  96161. </xs:choice>
  96162. </xs:sequence>
  96163. </xs:group>
  96164. <xs:complexType name="directoryFilterType">
  96165. <xs:simpleContent>
  96166. <xs:extension base="xs:anyURI">
  96167. <xs:attribute type="xs:string" name="prefix" default=""/>
  96168. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  96169. <xs:attributeGroup ref="phpVersionGroup"/>
  96170. </xs:extension>
  96171. </xs:simpleContent>
  96172. </xs:complexType>
  96173. <xs:simpleType name="executionOrderType">
  96174. <xs:restriction base="xs:string">
  96175. <xs:enumeration value="default"/>
  96176. <xs:enumeration value="defects"/>
  96177. <xs:enumeration value="depends"/>
  96178. <xs:enumeration value="depends,defects"/>
  96179. <xs:enumeration value="depends,duration"/>
  96180. <xs:enumeration value="depends,random"/>
  96181. <xs:enumeration value="depends,reverse"/>
  96182. <xs:enumeration value="depends,size"/>
  96183. <xs:enumeration value="duration"/>
  96184. <xs:enumeration value="no-depends"/>
  96185. <xs:enumeration value="no-depends,defects"/>
  96186. <xs:enumeration value="no-depends,duration"/>
  96187. <xs:enumeration value="no-depends,random"/>
  96188. <xs:enumeration value="no-depends,reverse"/>
  96189. <xs:enumeration value="no-depends,size"/>
  96190. <xs:enumeration value="random"/>
  96191. <xs:enumeration value="reverse"/>
  96192. <xs:enumeration value="size"/>
  96193. </xs:restriction>
  96194. </xs:simpleType>
  96195. <xs:complexType name="fileFilterType">
  96196. <xs:simpleContent>
  96197. <xs:extension base="xs:anyURI">
  96198. <xs:attributeGroup ref="phpVersionGroup"/>
  96199. </xs:extension>
  96200. </xs:simpleContent>
  96201. </xs:complexType>
  96202. <xs:attributeGroup name="phpVersionGroup">
  96203. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  96204. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  96205. </xs:attributeGroup>
  96206. <xs:complexType name="phpType">
  96207. <xs:sequence>
  96208. <xs:choice maxOccurs="unbounded">
  96209. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96210. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96211. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96212. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96213. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96214. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96215. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96216. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96217. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96218. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96219. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96220. </xs:choice>
  96221. </xs:sequence>
  96222. </xs:complexType>
  96223. <xs:complexType name="namedValueType">
  96224. <xs:attribute name="name" use="required" type="xs:string"/>
  96225. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  96226. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  96227. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  96228. </xs:complexType>
  96229. <xs:complexType name="phpUnitType">
  96230. <xs:annotation>
  96231. <xs:documentation>The main type specifying the document structure</xs:documentation>
  96232. </xs:annotation>
  96233. <xs:group ref="configGroup"/>
  96234. <xs:attributeGroup ref="configAttributeGroup"/>
  96235. </xs:complexType>
  96236. <xs:attributeGroup name="configAttributeGroup">
  96237. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  96238. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  96239. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  96240. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  96241. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  96242. <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
  96243. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  96244. <xs:attribute name="columns" type="columnsType" default="80"/>
  96245. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
  96246. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  96247. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  96248. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  96249. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  96250. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  96251. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
  96252. <xs:attribute name="printerFile" type="xs:anyURI"/>
  96253. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  96254. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  96255. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  96256. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  96257. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  96258. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  96259. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  96260. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  96261. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  96262. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  96263. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  96264. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  96265. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  96266. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  96267. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  96268. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  96269. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  96270. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  96271. <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
  96272. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  96273. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  96274. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  96275. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  96276. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  96277. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  96278. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  96279. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  96280. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  96281. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  96282. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  96283. <xs:attribute name="extensionsDirectory" type="xs:string"/>
  96284. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  96285. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  96286. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  96287. </xs:attributeGroup>
  96288. <xs:group name="configGroup">
  96289. <xs:all>
  96290. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  96291. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  96292. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  96293. <xs:element name="filter" type="filtersType" minOccurs="0"/>
  96294. <xs:element name="logging" type="loggersType" minOccurs="0"/>
  96295. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  96296. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  96297. <xs:element name="php" type="phpType" minOccurs="0"/>
  96298. </xs:all>
  96299. </xs:group>
  96300. <xs:element name="testSuiteFacet" abstract="true"/>
  96301. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  96302. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  96303. <xs:complexType name="testSuitesType">
  96304. <xs:sequence>
  96305. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  96306. </xs:sequence>
  96307. </xs:complexType>
  96308. <xs:complexType name="testSuiteType">
  96309. <xs:sequence>
  96310. <xs:group ref="pathGroup"/>
  96311. <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96312. </xs:sequence>
  96313. <xs:attribute name="name" type="xs:string" use="required"/>
  96314. </xs:complexType>
  96315. </xs:schema>
  96316. <?xml version="1.0" encoding="UTF-8"?>
  96317. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  96318. <xs:annotation>
  96319. <xs:documentation source="https://phpunit.de/documentation.html">
  96320. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured.
  96321. </xs:documentation>
  96322. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  96323. </xs:annotation>
  96324. <xs:element name="phpunit" type="phpUnitType">
  96325. <xs:annotation>
  96326. <xs:documentation>Root Element</xs:documentation>
  96327. </xs:annotation>
  96328. </xs:element>
  96329. <xs:complexType name="filtersType">
  96330. <xs:sequence>
  96331. <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
  96332. </xs:sequence>
  96333. </xs:complexType>
  96334. <xs:complexType name="filterType">
  96335. <xs:sequence>
  96336. <xs:choice maxOccurs="unbounded" minOccurs="0">
  96337. <xs:group ref="pathGroup"/>
  96338. <xs:element name="exclude">
  96339. <xs:complexType>
  96340. <xs:group ref="pathGroup"/>
  96341. </xs:complexType>
  96342. </xs:element>
  96343. </xs:choice>
  96344. </xs:sequence>
  96345. </xs:complexType>
  96346. <xs:complexType name="whiteListType">
  96347. <xs:complexContent>
  96348. <xs:extension base="filterType">
  96349. <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
  96350. <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
  96351. </xs:extension>
  96352. </xs:complexContent>
  96353. </xs:complexType>
  96354. <xs:complexType name="groupsType">
  96355. <xs:choice>
  96356. <xs:sequence>
  96357. <xs:element name="include" type="groupType"/>
  96358. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  96359. </xs:sequence>
  96360. <xs:sequence>
  96361. <xs:element name="exclude" type="groupType"/>
  96362. </xs:sequence>
  96363. </xs:choice>
  96364. </xs:complexType>
  96365. <xs:complexType name="groupType">
  96366. <xs:sequence>
  96367. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  96368. </xs:sequence>
  96369. </xs:complexType>
  96370. <xs:complexType name="extensionsType">
  96371. <xs:sequence>
  96372. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  96373. </xs:sequence>
  96374. </xs:complexType>
  96375. <xs:complexType name="listenersType">
  96376. <xs:sequence>
  96377. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  96378. </xs:sequence>
  96379. </xs:complexType>
  96380. <xs:complexType name="objectType">
  96381. <xs:sequence>
  96382. <xs:element name="arguments" minOccurs="0">
  96383. <xs:complexType>
  96384. <xs:group ref="argumentsGroup"/>
  96385. </xs:complexType>
  96386. </xs:element>
  96387. </xs:sequence>
  96388. <xs:attribute name="class" type="xs:string" use="required"/>
  96389. <xs:attribute name="file" type="xs:anyURI"/>
  96390. </xs:complexType>
  96391. <xs:complexType name="arrayType">
  96392. <xs:sequence>
  96393. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  96394. </xs:sequence>
  96395. </xs:complexType>
  96396. <xs:complexType name="argumentType">
  96397. <xs:group ref="argumentChoice"/>
  96398. <xs:attribute name="key" use="required"/>
  96399. </xs:complexType>
  96400. <xs:group name="argumentsGroup">
  96401. <xs:sequence>
  96402. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96403. <xs:element name="array" type="arrayType" />
  96404. <xs:element name="integer" type="xs:integer" />
  96405. <xs:element name="string" type="xs:string" />
  96406. <xs:element name="double" type="xs:double" />
  96407. <xs:element name="null" />
  96408. <xs:element name="object" type="objectType" />
  96409. <xs:element name="file" type="xs:anyURI" />
  96410. <xs:element name="directory" type="xs:anyURI" />
  96411. <xs:element name="boolean" type="xs:boolean" />
  96412. </xs:choice>
  96413. </xs:sequence>
  96414. </xs:group>
  96415. <xs:group name="argumentChoice">
  96416. <xs:choice>
  96417. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  96418. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  96419. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  96420. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  96421. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  96422. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  96423. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96424. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96425. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  96426. </xs:choice>
  96427. </xs:group>
  96428. <xs:simpleType name="columnsType">
  96429. <xs:union>
  96430. <xs:simpleType>
  96431. <xs:restriction base="xs:integer"/>
  96432. </xs:simpleType>
  96433. <xs:simpleType>
  96434. <xs:restriction base="xs:string">
  96435. <xs:enumeration value="max"/>
  96436. </xs:restriction>
  96437. </xs:simpleType>
  96438. </xs:union>
  96439. </xs:simpleType>
  96440. <xs:complexType name="loggersType">
  96441. <xs:sequence>
  96442. <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
  96443. </xs:sequence>
  96444. </xs:complexType>
  96445. <xs:complexType name="loggerType">
  96446. <xs:attribute name="type">
  96447. <xs:simpleType>
  96448. <xs:restriction base="xs:string">
  96449. <xs:enumeration value="coverage-html"/>
  96450. <xs:enumeration value="coverage-text"/>
  96451. <xs:enumeration value="coverage-clover"/>
  96452. <xs:enumeration value="coverage-crap4j"/>
  96453. <xs:enumeration value="coverage-xml"/>
  96454. <xs:enumeration value="coverage-php"/>
  96455. <xs:enumeration value="plain"/>
  96456. <xs:enumeration value="teamcity"/>
  96457. <xs:enumeration value="junit"/>
  96458. <xs:enumeration value="testdox-html"/>
  96459. <xs:enumeration value="testdox-text"/>
  96460. <xs:enumeration value="testdox-xml"/>
  96461. </xs:restriction>
  96462. </xs:simpleType>
  96463. </xs:attribute>
  96464. <xs:attribute name="target" type="xs:anyURI"/>
  96465. <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="35"/>
  96466. <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="70"/>
  96467. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  96468. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  96469. <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
  96470. </xs:complexType>
  96471. <xs:group name="pathGroup">
  96472. <xs:sequence>
  96473. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96474. <xs:element name="directory" type="directoryFilterType"/>
  96475. <xs:element name="file" type="fileFilterType"/>
  96476. </xs:choice>
  96477. </xs:sequence>
  96478. </xs:group>
  96479. <xs:complexType name="directoryFilterType">
  96480. <xs:simpleContent>
  96481. <xs:extension base="xs:anyURI">
  96482. <xs:attribute type="xs:string" name="prefix" default=""/>
  96483. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  96484. <xs:attributeGroup ref="phpVersionGroup"/>
  96485. </xs:extension>
  96486. </xs:simpleContent>
  96487. </xs:complexType>
  96488. <xs:simpleType name="executionOrderType">
  96489. <xs:restriction base="xs:string">
  96490. <xs:enumeration value="default"/>
  96491. <xs:enumeration value="defects"/>
  96492. <xs:enumeration value="depends"/>
  96493. <xs:enumeration value="depends,defects"/>
  96494. <xs:enumeration value="depends,duration"/>
  96495. <xs:enumeration value="depends,random"/>
  96496. <xs:enumeration value="depends,reverse"/>
  96497. <xs:enumeration value="depends,size"/>
  96498. <xs:enumeration value="duration"/>
  96499. <xs:enumeration value="no-depends"/>
  96500. <xs:enumeration value="no-depends,defects"/>
  96501. <xs:enumeration value="no-depends,duration"/>
  96502. <xs:enumeration value="no-depends,random"/>
  96503. <xs:enumeration value="no-depends,reverse"/>
  96504. <xs:enumeration value="no-depends,size"/>
  96505. <xs:enumeration value="random"/>
  96506. <xs:enumeration value="reverse"/>
  96507. <xs:enumeration value="size"/>
  96508. </xs:restriction>
  96509. </xs:simpleType>
  96510. <xs:complexType name="fileFilterType">
  96511. <xs:simpleContent>
  96512. <xs:extension base="xs:anyURI">
  96513. <xs:attributeGroup ref="phpVersionGroup"/>
  96514. </xs:extension>
  96515. </xs:simpleContent>
  96516. </xs:complexType>
  96517. <xs:attributeGroup name="phpVersionGroup">
  96518. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  96519. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  96520. </xs:attributeGroup>
  96521. <xs:complexType name="phpType">
  96522. <xs:sequence>
  96523. <xs:choice maxOccurs="unbounded">
  96524. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96525. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96526. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96527. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96528. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96529. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96530. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96531. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96532. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96533. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96534. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96535. </xs:choice>
  96536. </xs:sequence>
  96537. </xs:complexType>
  96538. <xs:complexType name="namedValueType">
  96539. <xs:attribute name="name" use="required" type="xs:string"/>
  96540. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  96541. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  96542. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  96543. </xs:complexType>
  96544. <xs:complexType name="phpUnitType">
  96545. <xs:annotation>
  96546. <xs:documentation>The main type specifying the document structure</xs:documentation>
  96547. </xs:annotation>
  96548. <xs:group ref="configGroup"/>
  96549. <xs:attributeGroup ref="configAttributeGroup"/>
  96550. </xs:complexType>
  96551. <xs:attributeGroup name="configAttributeGroup">
  96552. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  96553. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  96554. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  96555. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  96556. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  96557. <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
  96558. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  96559. <xs:attribute name="columns" type="columnsType" default="80"/>
  96560. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
  96561. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  96562. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  96563. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  96564. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  96565. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  96566. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
  96567. <xs:attribute name="printerFile" type="xs:anyURI"/>
  96568. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  96569. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  96570. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  96571. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  96572. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  96573. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  96574. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  96575. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  96576. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  96577. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  96578. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  96579. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  96580. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  96581. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  96582. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  96583. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  96584. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  96585. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  96586. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  96587. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  96588. <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
  96589. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  96590. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  96591. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  96592. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  96593. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  96594. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  96595. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  96596. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  96597. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  96598. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  96599. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  96600. <xs:attribute name="extensionsDirectory" type="xs:string"/>
  96601. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  96602. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  96603. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  96604. </xs:attributeGroup>
  96605. <xs:group name="configGroup">
  96606. <xs:all>
  96607. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  96608. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  96609. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  96610. <xs:element name="filter" type="filtersType" minOccurs="0"/>
  96611. <xs:element name="logging" type="loggersType" minOccurs="0"/>
  96612. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  96613. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  96614. <xs:element name="php" type="phpType" minOccurs="0"/>
  96615. </xs:all>
  96616. </xs:group>
  96617. <xs:element name="testSuiteFacet" abstract="true"/>
  96618. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  96619. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  96620. <xs:complexType name="testSuitesType">
  96621. <xs:sequence>
  96622. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  96623. </xs:sequence>
  96624. </xs:complexType>
  96625. <xs:complexType name="testSuiteType">
  96626. <xs:sequence>
  96627. <xs:group ref="pathGroup"/>
  96628. <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96629. </xs:sequence>
  96630. <xs:attribute name="name" type="xs:string" use="required"/>
  96631. </xs:complexType>
  96632. </xs:schema>
  96633. <?xml version="1.0" encoding="UTF-8"?>
  96634. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  96635. <xs:annotation>
  96636. <xs:documentation source="https://phpunit.de/documentation.html">
  96637. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.2 may be structured.
  96638. </xs:documentation>
  96639. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  96640. </xs:annotation>
  96641. <xs:element name="phpunit" type="phpUnitType">
  96642. <xs:annotation>
  96643. <xs:documentation>Root Element</xs:documentation>
  96644. </xs:annotation>
  96645. </xs:element>
  96646. <xs:complexType name="filtersType">
  96647. <xs:sequence>
  96648. <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
  96649. </xs:sequence>
  96650. </xs:complexType>
  96651. <xs:complexType name="filterType">
  96652. <xs:sequence>
  96653. <xs:choice maxOccurs="unbounded" minOccurs="0">
  96654. <xs:group ref="pathGroup"/>
  96655. <xs:element name="exclude">
  96656. <xs:complexType>
  96657. <xs:group ref="pathGroup"/>
  96658. </xs:complexType>
  96659. </xs:element>
  96660. </xs:choice>
  96661. </xs:sequence>
  96662. </xs:complexType>
  96663. <xs:complexType name="whiteListType">
  96664. <xs:complexContent>
  96665. <xs:extension base="filterType">
  96666. <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
  96667. <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
  96668. </xs:extension>
  96669. </xs:complexContent>
  96670. </xs:complexType>
  96671. <xs:complexType name="groupsType">
  96672. <xs:choice>
  96673. <xs:sequence>
  96674. <xs:element name="include" type="groupType"/>
  96675. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  96676. </xs:sequence>
  96677. <xs:sequence>
  96678. <xs:element name="exclude" type="groupType"/>
  96679. </xs:sequence>
  96680. </xs:choice>
  96681. </xs:complexType>
  96682. <xs:complexType name="groupType">
  96683. <xs:sequence>
  96684. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  96685. </xs:sequence>
  96686. </xs:complexType>
  96687. <xs:complexType name="extensionsType">
  96688. <xs:sequence>
  96689. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  96690. </xs:sequence>
  96691. </xs:complexType>
  96692. <xs:complexType name="listenersType">
  96693. <xs:sequence>
  96694. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  96695. </xs:sequence>
  96696. </xs:complexType>
  96697. <xs:complexType name="objectType">
  96698. <xs:sequence>
  96699. <xs:element name="arguments" minOccurs="0">
  96700. <xs:complexType>
  96701. <xs:group ref="argumentsGroup"/>
  96702. </xs:complexType>
  96703. </xs:element>
  96704. </xs:sequence>
  96705. <xs:attribute name="class" type="xs:string" use="required"/>
  96706. <xs:attribute name="file" type="xs:anyURI"/>
  96707. </xs:complexType>
  96708. <xs:complexType name="arrayType">
  96709. <xs:sequence>
  96710. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  96711. </xs:sequence>
  96712. </xs:complexType>
  96713. <xs:complexType name="argumentType">
  96714. <xs:group ref="argumentChoice"/>
  96715. <xs:attribute name="key" use="required"/>
  96716. </xs:complexType>
  96717. <xs:group name="argumentsGroup">
  96718. <xs:sequence>
  96719. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96720. <xs:element name="array" type="arrayType" />
  96721. <xs:element name="integer" type="xs:integer" />
  96722. <xs:element name="string" type="xs:string" />
  96723. <xs:element name="double" type="xs:double" />
  96724. <xs:element name="null" />
  96725. <xs:element name="object" type="objectType" />
  96726. <xs:element name="file" type="xs:anyURI" />
  96727. <xs:element name="directory" type="xs:anyURI" />
  96728. <xs:element name="boolean" type="xs:boolean" />
  96729. </xs:choice>
  96730. </xs:sequence>
  96731. </xs:group>
  96732. <xs:group name="argumentChoice">
  96733. <xs:choice>
  96734. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  96735. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  96736. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  96737. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  96738. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  96739. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  96740. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96741. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96742. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  96743. </xs:choice>
  96744. </xs:group>
  96745. <xs:simpleType name="columnsType">
  96746. <xs:union>
  96747. <xs:simpleType>
  96748. <xs:restriction base="xs:integer"/>
  96749. </xs:simpleType>
  96750. <xs:simpleType>
  96751. <xs:restriction base="xs:string">
  96752. <xs:enumeration value="max"/>
  96753. </xs:restriction>
  96754. </xs:simpleType>
  96755. </xs:union>
  96756. </xs:simpleType>
  96757. <xs:complexType name="loggersType">
  96758. <xs:sequence>
  96759. <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
  96760. </xs:sequence>
  96761. </xs:complexType>
  96762. <xs:complexType name="loggerType">
  96763. <xs:attribute name="type">
  96764. <xs:simpleType>
  96765. <xs:restriction base="xs:string">
  96766. <xs:enumeration value="coverage-html"/>
  96767. <xs:enumeration value="coverage-text"/>
  96768. <xs:enumeration value="coverage-clover"/>
  96769. <xs:enumeration value="coverage-crap4j"/>
  96770. <xs:enumeration value="coverage-xml"/>
  96771. <xs:enumeration value="coverage-php"/>
  96772. <xs:enumeration value="plain"/>
  96773. <xs:enumeration value="teamcity"/>
  96774. <xs:enumeration value="junit"/>
  96775. <xs:enumeration value="testdox-html"/>
  96776. <xs:enumeration value="testdox-text"/>
  96777. <xs:enumeration value="testdox-xml"/>
  96778. </xs:restriction>
  96779. </xs:simpleType>
  96780. </xs:attribute>
  96781. <xs:attribute name="target" type="xs:anyURI"/>
  96782. <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="50"/>
  96783. <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="90"/>
  96784. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  96785. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  96786. <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
  96787. </xs:complexType>
  96788. <xs:group name="pathGroup">
  96789. <xs:sequence>
  96790. <xs:choice minOccurs="0" maxOccurs="unbounded">
  96791. <xs:element name="directory" type="directoryFilterType"/>
  96792. <xs:element name="file" type="fileFilterType"/>
  96793. </xs:choice>
  96794. </xs:sequence>
  96795. </xs:group>
  96796. <xs:complexType name="directoryFilterType">
  96797. <xs:simpleContent>
  96798. <xs:extension base="xs:anyURI">
  96799. <xs:attribute type="xs:string" name="prefix" default=""/>
  96800. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  96801. <xs:attributeGroup ref="phpVersionGroup"/>
  96802. </xs:extension>
  96803. </xs:simpleContent>
  96804. </xs:complexType>
  96805. <xs:simpleType name="executionOrderType">
  96806. <xs:restriction base="xs:string">
  96807. <xs:enumeration value="default"/>
  96808. <xs:enumeration value="defects"/>
  96809. <xs:enumeration value="depends"/>
  96810. <xs:enumeration value="depends,defects"/>
  96811. <xs:enumeration value="depends,duration"/>
  96812. <xs:enumeration value="depends,random"/>
  96813. <xs:enumeration value="depends,reverse"/>
  96814. <xs:enumeration value="depends,size"/>
  96815. <xs:enumeration value="duration"/>
  96816. <xs:enumeration value="no-depends"/>
  96817. <xs:enumeration value="no-depends,defects"/>
  96818. <xs:enumeration value="no-depends,duration"/>
  96819. <xs:enumeration value="no-depends,random"/>
  96820. <xs:enumeration value="no-depends,reverse"/>
  96821. <xs:enumeration value="no-depends,size"/>
  96822. <xs:enumeration value="random"/>
  96823. <xs:enumeration value="reverse"/>
  96824. <xs:enumeration value="size"/>
  96825. </xs:restriction>
  96826. </xs:simpleType>
  96827. <xs:complexType name="fileFilterType">
  96828. <xs:simpleContent>
  96829. <xs:extension base="xs:anyURI">
  96830. <xs:attributeGroup ref="phpVersionGroup"/>
  96831. </xs:extension>
  96832. </xs:simpleContent>
  96833. </xs:complexType>
  96834. <xs:attributeGroup name="phpVersionGroup">
  96835. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  96836. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  96837. </xs:attributeGroup>
  96838. <xs:complexType name="phpType">
  96839. <xs:sequence>
  96840. <xs:choice maxOccurs="unbounded">
  96841. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96842. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96843. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96844. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96845. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96846. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96847. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96848. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96849. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96850. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96851. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  96852. </xs:choice>
  96853. </xs:sequence>
  96854. </xs:complexType>
  96855. <xs:complexType name="namedValueType">
  96856. <xs:attribute name="name" use="required" type="xs:string"/>
  96857. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  96858. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  96859. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  96860. </xs:complexType>
  96861. <xs:complexType name="phpUnitType">
  96862. <xs:annotation>
  96863. <xs:documentation>The main type specifying the document structure</xs:documentation>
  96864. </xs:annotation>
  96865. <xs:group ref="configGroup"/>
  96866. <xs:attributeGroup ref="configAttributeGroup"/>
  96867. </xs:complexType>
  96868. <xs:attributeGroup name="configAttributeGroup">
  96869. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  96870. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  96871. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  96872. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  96873. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  96874. <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
  96875. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  96876. <xs:attribute name="columns" type="columnsType" default="80"/>
  96877. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
  96878. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  96879. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  96880. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  96881. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  96882. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  96883. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
  96884. <xs:attribute name="printerFile" type="xs:anyURI"/>
  96885. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  96886. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  96887. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  96888. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  96889. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  96890. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  96891. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  96892. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  96893. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  96894. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  96895. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  96896. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  96897. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  96898. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  96899. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  96900. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  96901. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  96902. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  96903. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  96904. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  96905. <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
  96906. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  96907. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  96908. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  96909. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  96910. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  96911. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  96912. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  96913. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  96914. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  96915. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  96916. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  96917. <xs:attribute name="extensionsDirectory" type="xs:string"/>
  96918. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  96919. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  96920. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  96921. </xs:attributeGroup>
  96922. <xs:group name="configGroup">
  96923. <xs:all>
  96924. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  96925. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  96926. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  96927. <xs:element name="filter" type="filtersType" minOccurs="0"/>
  96928. <xs:element name="logging" type="loggersType" minOccurs="0"/>
  96929. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  96930. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  96931. <xs:element name="php" type="phpType" minOccurs="0"/>
  96932. </xs:all>
  96933. </xs:group>
  96934. <xs:element name="testSuiteFacet" abstract="true"/>
  96935. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  96936. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  96937. <xs:complexType name="testSuitesType">
  96938. <xs:sequence>
  96939. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  96940. </xs:sequence>
  96941. </xs:complexType>
  96942. <xs:complexType name="testSuiteType">
  96943. <xs:sequence>
  96944. <xs:group ref="pathGroup"/>
  96945. <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  96946. </xs:sequence>
  96947. <xs:attribute name="name" type="xs:string" use="required"/>
  96948. </xs:complexType>
  96949. </xs:schema>
  96950. <?xml version="1.0" encoding="UTF-8"?>
  96951. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  96952. <xs:annotation>
  96953. <xs:documentation source="https://phpunit.de/documentation.html">
  96954. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.3 may be structured.
  96955. </xs:documentation>
  96956. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  96957. </xs:annotation>
  96958. <xs:element name="phpunit" type="phpUnitType">
  96959. <xs:annotation>
  96960. <xs:documentation>Root Element</xs:documentation>
  96961. </xs:annotation>
  96962. </xs:element>
  96963. <xs:complexType name="coverageType">
  96964. <xs:all>
  96965. <xs:element name="include" minOccurs="0" maxOccurs="1">
  96966. <xs:complexType>
  96967. <xs:group ref="pathGroup"/>
  96968. </xs:complexType>
  96969. </xs:element>
  96970. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  96971. <xs:complexType>
  96972. <xs:group ref="pathGroup"/>
  96973. </xs:complexType>
  96974. </xs:element>
  96975. <xs:element name="report" minOccurs="0" maxOccurs="1">
  96976. <xs:complexType>
  96977. <xs:group ref="coverageReportGroup"/>
  96978. </xs:complexType>
  96979. </xs:element>
  96980. </xs:all>
  96981. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  96982. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  96983. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  96984. <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
  96985. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  96986. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  96987. </xs:complexType>
  96988. <xs:complexType name="loggingType">
  96989. <xs:group ref="loggingGroup"/>
  96990. </xs:complexType>
  96991. <xs:complexType name="groupsType">
  96992. <xs:choice>
  96993. <xs:sequence>
  96994. <xs:element name="include" type="groupType"/>
  96995. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  96996. </xs:sequence>
  96997. <xs:sequence>
  96998. <xs:element name="exclude" type="groupType"/>
  96999. </xs:sequence>
  97000. </xs:choice>
  97001. </xs:complexType>
  97002. <xs:complexType name="groupType">
  97003. <xs:sequence>
  97004. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  97005. </xs:sequence>
  97006. </xs:complexType>
  97007. <xs:complexType name="extensionsType">
  97008. <xs:sequence>
  97009. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  97010. </xs:sequence>
  97011. </xs:complexType>
  97012. <xs:complexType name="listenersType">
  97013. <xs:sequence>
  97014. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  97015. </xs:sequence>
  97016. </xs:complexType>
  97017. <xs:complexType name="objectType">
  97018. <xs:sequence>
  97019. <xs:element name="arguments" minOccurs="0">
  97020. <xs:complexType>
  97021. <xs:group ref="argumentsGroup"/>
  97022. </xs:complexType>
  97023. </xs:element>
  97024. </xs:sequence>
  97025. <xs:attribute name="class" type="xs:string" use="required"/>
  97026. <xs:attribute name="file" type="xs:anyURI"/>
  97027. </xs:complexType>
  97028. <xs:complexType name="arrayType">
  97029. <xs:sequence>
  97030. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  97031. </xs:sequence>
  97032. </xs:complexType>
  97033. <xs:complexType name="argumentType">
  97034. <xs:group ref="argumentChoice"/>
  97035. <xs:attribute name="key" use="required"/>
  97036. </xs:complexType>
  97037. <xs:group name="argumentsGroup">
  97038. <xs:sequence>
  97039. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97040. <xs:element name="array" type="arrayType" />
  97041. <xs:element name="integer" type="xs:integer" />
  97042. <xs:element name="string" type="xs:string" />
  97043. <xs:element name="double" type="xs:double" />
  97044. <xs:element name="null" />
  97045. <xs:element name="object" type="objectType" />
  97046. <xs:element name="file" type="xs:anyURI" />
  97047. <xs:element name="directory" type="xs:anyURI" />
  97048. <xs:element name="boolean" type="xs:boolean" />
  97049. </xs:choice>
  97050. </xs:sequence>
  97051. </xs:group>
  97052. <xs:group name="argumentChoice">
  97053. <xs:choice>
  97054. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  97055. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  97056. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  97057. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  97058. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  97059. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  97060. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97061. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97062. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  97063. </xs:choice>
  97064. </xs:group>
  97065. <xs:simpleType name="columnsType">
  97066. <xs:union>
  97067. <xs:simpleType>
  97068. <xs:restriction base="xs:integer"/>
  97069. </xs:simpleType>
  97070. <xs:simpleType>
  97071. <xs:restriction base="xs:string">
  97072. <xs:enumeration value="max"/>
  97073. </xs:restriction>
  97074. </xs:simpleType>
  97075. </xs:union>
  97076. </xs:simpleType>
  97077. <xs:group name="pathGroup">
  97078. <xs:sequence>
  97079. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97080. <xs:element name="directory" type="directoryFilterType"/>
  97081. <xs:element name="file" type="fileFilterType"/>
  97082. </xs:choice>
  97083. </xs:sequence>
  97084. </xs:group>
  97085. <xs:complexType name="directoryFilterType">
  97086. <xs:simpleContent>
  97087. <xs:extension base="xs:anyURI">
  97088. <xs:attribute type="xs:string" name="prefix" default=""/>
  97089. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  97090. <xs:attributeGroup ref="phpVersionGroup"/>
  97091. </xs:extension>
  97092. </xs:simpleContent>
  97093. </xs:complexType>
  97094. <xs:simpleType name="executionOrderType">
  97095. <xs:restriction base="xs:string">
  97096. <xs:enumeration value="default"/>
  97097. <xs:enumeration value="defects"/>
  97098. <xs:enumeration value="depends"/>
  97099. <xs:enumeration value="depends,defects"/>
  97100. <xs:enumeration value="depends,duration"/>
  97101. <xs:enumeration value="depends,random"/>
  97102. <xs:enumeration value="depends,reverse"/>
  97103. <xs:enumeration value="depends,size"/>
  97104. <xs:enumeration value="duration"/>
  97105. <xs:enumeration value="no-depends"/>
  97106. <xs:enumeration value="no-depends,defects"/>
  97107. <xs:enumeration value="no-depends,duration"/>
  97108. <xs:enumeration value="no-depends,random"/>
  97109. <xs:enumeration value="no-depends,reverse"/>
  97110. <xs:enumeration value="no-depends,size"/>
  97111. <xs:enumeration value="random"/>
  97112. <xs:enumeration value="reverse"/>
  97113. <xs:enumeration value="size"/>
  97114. </xs:restriction>
  97115. </xs:simpleType>
  97116. <xs:complexType name="fileFilterType">
  97117. <xs:simpleContent>
  97118. <xs:extension base="xs:anyURI">
  97119. <xs:attributeGroup ref="phpVersionGroup"/>
  97120. </xs:extension>
  97121. </xs:simpleContent>
  97122. </xs:complexType>
  97123. <xs:attributeGroup name="phpVersionGroup">
  97124. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  97125. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  97126. </xs:attributeGroup>
  97127. <xs:complexType name="phpType">
  97128. <xs:sequence>
  97129. <xs:choice maxOccurs="unbounded">
  97130. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97131. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97132. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97133. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97134. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97135. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97136. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97137. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97138. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97139. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97140. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97141. </xs:choice>
  97142. </xs:sequence>
  97143. </xs:complexType>
  97144. <xs:complexType name="namedValueType">
  97145. <xs:attribute name="name" use="required" type="xs:string"/>
  97146. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  97147. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  97148. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  97149. </xs:complexType>
  97150. <xs:complexType name="phpUnitType">
  97151. <xs:annotation>
  97152. <xs:documentation>The main type specifying the document structure</xs:documentation>
  97153. </xs:annotation>
  97154. <xs:group ref="configGroup"/>
  97155. <xs:attributeGroup ref="configAttributeGroup"/>
  97156. </xs:complexType>
  97157. <xs:attributeGroup name="configAttributeGroup">
  97158. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  97159. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  97160. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  97161. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  97162. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  97163. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  97164. <xs:attribute name="columns" type="columnsType" default="80"/>
  97165. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
  97166. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  97167. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  97168. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  97169. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  97170. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
  97171. <xs:attribute name="printerFile" type="xs:anyURI"/>
  97172. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  97173. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  97174. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  97175. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  97176. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  97177. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  97178. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  97179. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  97180. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  97181. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  97182. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  97183. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  97184. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  97185. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  97186. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  97187. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  97188. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  97189. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  97190. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  97191. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  97192. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  97193. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  97194. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  97195. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  97196. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  97197. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  97198. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  97199. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  97200. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  97201. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  97202. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  97203. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  97204. <xs:attribute name="extensionsDirectory" type="xs:string"/>
  97205. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  97206. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  97207. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  97208. </xs:attributeGroup>
  97209. <xs:group name="configGroup">
  97210. <xs:all>
  97211. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  97212. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  97213. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  97214. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  97215. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  97216. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  97217. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  97218. <xs:element name="php" type="phpType" minOccurs="0"/>
  97219. </xs:all>
  97220. </xs:group>
  97221. <xs:element name="testSuiteFacet" abstract="true"/>
  97222. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  97223. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  97224. <xs:complexType name="testSuitesType">
  97225. <xs:sequence>
  97226. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  97227. </xs:sequence>
  97228. </xs:complexType>
  97229. <xs:complexType name="testSuiteType">
  97230. <xs:sequence>
  97231. <xs:group ref="pathGroup"/>
  97232. <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97233. </xs:sequence>
  97234. <xs:attribute name="name" type="xs:string" use="required"/>
  97235. </xs:complexType>
  97236. <xs:group name="coverageReportGroup">
  97237. <xs:all>
  97238. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  97239. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  97240. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  97241. <xs:element name="php" type="logToFileType" minOccurs="0" />
  97242. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  97243. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  97244. </xs:all>
  97245. </xs:group>
  97246. <xs:group name="loggingGroup">
  97247. <xs:all>
  97248. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  97249. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  97250. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  97251. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  97252. <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
  97253. <xs:element name="text" type="logToFileType" minOccurs="0"/>
  97254. </xs:all>
  97255. </xs:group>
  97256. <xs:complexType name="logToFileType">
  97257. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97258. </xs:complexType>
  97259. <xs:complexType name="logToDirectoryType">
  97260. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97261. </xs:complexType>
  97262. <xs:complexType name="coverageReportCrap4JType">
  97263. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97264. <xs:attribute name="threshold" type="xs:integer"/>
  97265. </xs:complexType>
  97266. <xs:complexType name="coverageReportHtmlType">
  97267. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97268. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  97269. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  97270. </xs:complexType>
  97271. <xs:complexType name="coverageReportTextType">
  97272. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97273. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  97274. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  97275. </xs:complexType>
  97276. </xs:schema>
  97277. <?xml version="1.0" encoding="UTF-8"?>
  97278. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  97279. <xs:annotation>
  97280. <xs:documentation source="https://phpunit.de/documentation.html">
  97281. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.4 may be structured.
  97282. </xs:documentation>
  97283. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  97284. </xs:annotation>
  97285. <xs:element name="phpunit" type="phpUnitType">
  97286. <xs:annotation>
  97287. <xs:documentation>Root Element</xs:documentation>
  97288. </xs:annotation>
  97289. </xs:element>
  97290. <xs:complexType name="coverageType">
  97291. <xs:all>
  97292. <xs:element name="include" minOccurs="0" maxOccurs="1">
  97293. <xs:complexType>
  97294. <xs:group ref="pathGroup"/>
  97295. </xs:complexType>
  97296. </xs:element>
  97297. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  97298. <xs:complexType>
  97299. <xs:group ref="pathGroup"/>
  97300. </xs:complexType>
  97301. </xs:element>
  97302. <xs:element name="report" minOccurs="0" maxOccurs="1">
  97303. <xs:complexType>
  97304. <xs:group ref="coverageReportGroup"/>
  97305. </xs:complexType>
  97306. </xs:element>
  97307. </xs:all>
  97308. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  97309. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  97310. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  97311. <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
  97312. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  97313. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  97314. </xs:complexType>
  97315. <xs:complexType name="loggingType">
  97316. <xs:group ref="loggingGroup"/>
  97317. </xs:complexType>
  97318. <xs:complexType name="groupsType">
  97319. <xs:choice>
  97320. <xs:sequence>
  97321. <xs:element name="include" type="groupType"/>
  97322. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  97323. </xs:sequence>
  97324. <xs:sequence>
  97325. <xs:element name="exclude" type="groupType"/>
  97326. </xs:sequence>
  97327. </xs:choice>
  97328. </xs:complexType>
  97329. <xs:complexType name="groupType">
  97330. <xs:sequence>
  97331. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  97332. </xs:sequence>
  97333. </xs:complexType>
  97334. <xs:complexType name="extensionsType">
  97335. <xs:sequence>
  97336. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  97337. </xs:sequence>
  97338. </xs:complexType>
  97339. <xs:complexType name="listenersType">
  97340. <xs:sequence>
  97341. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  97342. </xs:sequence>
  97343. </xs:complexType>
  97344. <xs:complexType name="objectType">
  97345. <xs:sequence>
  97346. <xs:element name="arguments" minOccurs="0">
  97347. <xs:complexType>
  97348. <xs:group ref="argumentsGroup"/>
  97349. </xs:complexType>
  97350. </xs:element>
  97351. </xs:sequence>
  97352. <xs:attribute name="class" type="xs:string" use="required"/>
  97353. <xs:attribute name="file" type="xs:anyURI"/>
  97354. </xs:complexType>
  97355. <xs:complexType name="arrayType">
  97356. <xs:sequence>
  97357. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  97358. </xs:sequence>
  97359. </xs:complexType>
  97360. <xs:complexType name="argumentType">
  97361. <xs:group ref="argumentChoice"/>
  97362. <xs:attribute name="key" use="required"/>
  97363. </xs:complexType>
  97364. <xs:group name="argumentsGroup">
  97365. <xs:sequence>
  97366. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97367. <xs:element name="array" type="arrayType" />
  97368. <xs:element name="integer" type="xs:integer" />
  97369. <xs:element name="string" type="xs:string" />
  97370. <xs:element name="double" type="xs:double" />
  97371. <xs:element name="null" />
  97372. <xs:element name="object" type="objectType" />
  97373. <xs:element name="file" type="xs:anyURI" />
  97374. <xs:element name="directory" type="xs:anyURI" />
  97375. <xs:element name="boolean" type="xs:boolean" />
  97376. </xs:choice>
  97377. </xs:sequence>
  97378. </xs:group>
  97379. <xs:group name="argumentChoice">
  97380. <xs:choice>
  97381. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  97382. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  97383. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  97384. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  97385. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  97386. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  97387. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97388. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97389. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  97390. </xs:choice>
  97391. </xs:group>
  97392. <xs:simpleType name="columnsType">
  97393. <xs:union>
  97394. <xs:simpleType>
  97395. <xs:restriction base="xs:integer"/>
  97396. </xs:simpleType>
  97397. <xs:simpleType>
  97398. <xs:restriction base="xs:string">
  97399. <xs:enumeration value="max"/>
  97400. </xs:restriction>
  97401. </xs:simpleType>
  97402. </xs:union>
  97403. </xs:simpleType>
  97404. <xs:group name="pathGroup">
  97405. <xs:sequence>
  97406. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97407. <xs:element name="directory" type="directoryFilterType"/>
  97408. <xs:element name="file" type="fileFilterType"/>
  97409. </xs:choice>
  97410. </xs:sequence>
  97411. </xs:group>
  97412. <xs:complexType name="directoryFilterType">
  97413. <xs:simpleContent>
  97414. <xs:extension base="xs:anyURI">
  97415. <xs:attribute type="xs:string" name="prefix" default=""/>
  97416. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  97417. <xs:attributeGroup ref="phpVersionGroup"/>
  97418. </xs:extension>
  97419. </xs:simpleContent>
  97420. </xs:complexType>
  97421. <xs:simpleType name="executionOrderType">
  97422. <xs:restriction base="xs:string">
  97423. <xs:enumeration value="default"/>
  97424. <xs:enumeration value="defects"/>
  97425. <xs:enumeration value="depends"/>
  97426. <xs:enumeration value="depends,defects"/>
  97427. <xs:enumeration value="depends,duration"/>
  97428. <xs:enumeration value="depends,random"/>
  97429. <xs:enumeration value="depends,reverse"/>
  97430. <xs:enumeration value="depends,size"/>
  97431. <xs:enumeration value="duration"/>
  97432. <xs:enumeration value="no-depends"/>
  97433. <xs:enumeration value="no-depends,defects"/>
  97434. <xs:enumeration value="no-depends,duration"/>
  97435. <xs:enumeration value="no-depends,random"/>
  97436. <xs:enumeration value="no-depends,reverse"/>
  97437. <xs:enumeration value="no-depends,size"/>
  97438. <xs:enumeration value="random"/>
  97439. <xs:enumeration value="reverse"/>
  97440. <xs:enumeration value="size"/>
  97441. </xs:restriction>
  97442. </xs:simpleType>
  97443. <xs:complexType name="fileFilterType">
  97444. <xs:simpleContent>
  97445. <xs:extension base="xs:anyURI">
  97446. <xs:attributeGroup ref="phpVersionGroup"/>
  97447. </xs:extension>
  97448. </xs:simpleContent>
  97449. </xs:complexType>
  97450. <xs:attributeGroup name="phpVersionGroup">
  97451. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  97452. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  97453. </xs:attributeGroup>
  97454. <xs:complexType name="phpType">
  97455. <xs:sequence>
  97456. <xs:choice maxOccurs="unbounded">
  97457. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97458. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97459. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97460. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97461. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97462. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97463. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97464. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97465. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97466. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97467. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97468. </xs:choice>
  97469. </xs:sequence>
  97470. </xs:complexType>
  97471. <xs:complexType name="namedValueType">
  97472. <xs:attribute name="name" use="required" type="xs:string"/>
  97473. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  97474. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  97475. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  97476. </xs:complexType>
  97477. <xs:complexType name="phpUnitType">
  97478. <xs:annotation>
  97479. <xs:documentation>The main type specifying the document structure</xs:documentation>
  97480. </xs:annotation>
  97481. <xs:group ref="configGroup"/>
  97482. <xs:attributeGroup ref="configAttributeGroup"/>
  97483. </xs:complexType>
  97484. <xs:attributeGroup name="configAttributeGroup">
  97485. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  97486. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  97487. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  97488. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  97489. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  97490. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  97491. <xs:attribute name="columns" type="columnsType" default="80"/>
  97492. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
  97493. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  97494. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  97495. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  97496. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  97497. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
  97498. <xs:attribute name="printerFile" type="xs:anyURI"/>
  97499. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  97500. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  97501. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  97502. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  97503. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  97504. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  97505. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  97506. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  97507. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  97508. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  97509. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  97510. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  97511. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  97512. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  97513. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  97514. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  97515. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  97516. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  97517. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  97518. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  97519. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  97520. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  97521. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  97522. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  97523. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  97524. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  97525. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  97526. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  97527. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  97528. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  97529. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  97530. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  97531. <xs:attribute name="extensionsDirectory" type="xs:string"/>
  97532. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  97533. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  97534. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  97535. </xs:attributeGroup>
  97536. <xs:group name="configGroup">
  97537. <xs:all>
  97538. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  97539. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  97540. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  97541. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  97542. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  97543. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  97544. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  97545. <xs:element name="php" type="phpType" minOccurs="0"/>
  97546. </xs:all>
  97547. </xs:group>
  97548. <xs:element name="testSuiteFacet" abstract="true"/>
  97549. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  97550. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  97551. <xs:complexType name="testSuitesType">
  97552. <xs:sequence>
  97553. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  97554. </xs:sequence>
  97555. </xs:complexType>
  97556. <xs:complexType name="testSuiteType">
  97557. <xs:sequence>
  97558. <xs:group ref="pathGroup"/>
  97559. <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97560. </xs:sequence>
  97561. <xs:attribute name="name" type="xs:string" use="required"/>
  97562. </xs:complexType>
  97563. <xs:group name="coverageReportGroup">
  97564. <xs:all>
  97565. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  97566. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  97567. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  97568. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  97569. <xs:element name="php" type="logToFileType" minOccurs="0" />
  97570. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  97571. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  97572. </xs:all>
  97573. </xs:group>
  97574. <xs:group name="loggingGroup">
  97575. <xs:all>
  97576. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  97577. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  97578. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  97579. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  97580. <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
  97581. <xs:element name="text" type="logToFileType" minOccurs="0"/>
  97582. </xs:all>
  97583. </xs:group>
  97584. <xs:complexType name="logToFileType">
  97585. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97586. </xs:complexType>
  97587. <xs:complexType name="logToDirectoryType">
  97588. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97589. </xs:complexType>
  97590. <xs:complexType name="coverageReportCrap4JType">
  97591. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97592. <xs:attribute name="threshold" type="xs:integer"/>
  97593. </xs:complexType>
  97594. <xs:complexType name="coverageReportHtmlType">
  97595. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97596. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  97597. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  97598. </xs:complexType>
  97599. <xs:complexType name="coverageReportTextType">
  97600. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97601. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  97602. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  97603. </xs:complexType>
  97604. </xs:schema>
  97605. <?xml version="1.0" encoding="UTF-8"?>
  97606. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  97607. <xs:annotation>
  97608. <xs:documentation source="https://phpunit.de/documentation.html">
  97609. This Schema file defines the rules by which the XML configuration file of PHPUnit 9.5 may be structured.
  97610. </xs:documentation>
  97611. <xs:appinfo source="https://phpunit.de/documentation.html"/>
  97612. </xs:annotation>
  97613. <xs:element name="phpunit" type="phpUnitType">
  97614. <xs:annotation>
  97615. <xs:documentation>Root Element</xs:documentation>
  97616. </xs:annotation>
  97617. </xs:element>
  97618. <xs:complexType name="coverageType">
  97619. <xs:all>
  97620. <xs:element name="include" minOccurs="0" maxOccurs="1">
  97621. <xs:complexType>
  97622. <xs:group ref="pathGroup"/>
  97623. </xs:complexType>
  97624. </xs:element>
  97625. <xs:element name="exclude" minOccurs="0" maxOccurs="1">
  97626. <xs:complexType>
  97627. <xs:group ref="pathGroup"/>
  97628. </xs:complexType>
  97629. </xs:element>
  97630. <xs:element name="report" minOccurs="0" maxOccurs="1">
  97631. <xs:complexType>
  97632. <xs:group ref="coverageReportGroup"/>
  97633. </xs:complexType>
  97634. </xs:element>
  97635. </xs:all>
  97636. <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
  97637. <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
  97638. <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
  97639. <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
  97640. <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
  97641. <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
  97642. </xs:complexType>
  97643. <xs:complexType name="loggingType">
  97644. <xs:group ref="loggingGroup"/>
  97645. </xs:complexType>
  97646. <xs:complexType name="groupsType">
  97647. <xs:choice>
  97648. <xs:sequence>
  97649. <xs:element name="include" type="groupType"/>
  97650. <xs:element name="exclude" type="groupType" minOccurs="0"/>
  97651. </xs:sequence>
  97652. <xs:sequence>
  97653. <xs:element name="exclude" type="groupType"/>
  97654. </xs:sequence>
  97655. </xs:choice>
  97656. </xs:complexType>
  97657. <xs:complexType name="groupType">
  97658. <xs:sequence>
  97659. <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
  97660. </xs:sequence>
  97661. </xs:complexType>
  97662. <xs:complexType name="extensionsType">
  97663. <xs:sequence>
  97664. <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
  97665. </xs:sequence>
  97666. </xs:complexType>
  97667. <xs:complexType name="listenersType">
  97668. <xs:sequence>
  97669. <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
  97670. </xs:sequence>
  97671. </xs:complexType>
  97672. <xs:complexType name="objectType">
  97673. <xs:sequence>
  97674. <xs:element name="arguments" minOccurs="0">
  97675. <xs:complexType>
  97676. <xs:group ref="argumentsGroup"/>
  97677. </xs:complexType>
  97678. </xs:element>
  97679. </xs:sequence>
  97680. <xs:attribute name="class" type="xs:string" use="required"/>
  97681. <xs:attribute name="file" type="xs:anyURI"/>
  97682. </xs:complexType>
  97683. <xs:complexType name="arrayType">
  97684. <xs:sequence>
  97685. <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
  97686. </xs:sequence>
  97687. </xs:complexType>
  97688. <xs:complexType name="argumentType">
  97689. <xs:group ref="argumentChoice"/>
  97690. <xs:attribute name="key" use="required"/>
  97691. </xs:complexType>
  97692. <xs:group name="argumentsGroup">
  97693. <xs:sequence>
  97694. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97695. <xs:element name="array" type="arrayType" />
  97696. <xs:element name="integer" type="xs:integer" />
  97697. <xs:element name="string" type="xs:string" />
  97698. <xs:element name="double" type="xs:double" />
  97699. <xs:element name="null" />
  97700. <xs:element name="object" type="objectType" />
  97701. <xs:element name="file" type="xs:anyURI" />
  97702. <xs:element name="directory" type="xs:anyURI" />
  97703. <xs:element name="boolean" type="xs:boolean" />
  97704. </xs:choice>
  97705. </xs:sequence>
  97706. </xs:group>
  97707. <xs:group name="argumentChoice">
  97708. <xs:choice>
  97709. <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
  97710. <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  97711. <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  97712. <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
  97713. <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
  97714. <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
  97715. <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97716. <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97717. <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
  97718. </xs:choice>
  97719. </xs:group>
  97720. <xs:simpleType name="columnsType">
  97721. <xs:union>
  97722. <xs:simpleType>
  97723. <xs:restriction base="xs:integer"/>
  97724. </xs:simpleType>
  97725. <xs:simpleType>
  97726. <xs:restriction base="xs:string">
  97727. <xs:enumeration value="max"/>
  97728. </xs:restriction>
  97729. </xs:simpleType>
  97730. </xs:union>
  97731. </xs:simpleType>
  97732. <xs:group name="pathGroup">
  97733. <xs:sequence>
  97734. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97735. <xs:element name="directory" type="directoryFilterType"/>
  97736. <xs:element name="file" type="fileFilterType"/>
  97737. </xs:choice>
  97738. </xs:sequence>
  97739. </xs:group>
  97740. <xs:complexType name="directoryFilterType">
  97741. <xs:simpleContent>
  97742. <xs:extension base="xs:string">
  97743. <xs:attribute type="xs:string" name="prefix" default=""/>
  97744. <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
  97745. <xs:attributeGroup ref="phpVersionGroup"/>
  97746. </xs:extension>
  97747. </xs:simpleContent>
  97748. </xs:complexType>
  97749. <xs:simpleType name="executionOrderType">
  97750. <xs:restriction base="xs:string">
  97751. <xs:enumeration value="default"/>
  97752. <xs:enumeration value="defects"/>
  97753. <xs:enumeration value="depends"/>
  97754. <xs:enumeration value="depends,defects"/>
  97755. <xs:enumeration value="depends,duration"/>
  97756. <xs:enumeration value="depends,random"/>
  97757. <xs:enumeration value="depends,reverse"/>
  97758. <xs:enumeration value="depends,size"/>
  97759. <xs:enumeration value="duration"/>
  97760. <xs:enumeration value="no-depends"/>
  97761. <xs:enumeration value="no-depends,defects"/>
  97762. <xs:enumeration value="no-depends,duration"/>
  97763. <xs:enumeration value="no-depends,random"/>
  97764. <xs:enumeration value="no-depends,reverse"/>
  97765. <xs:enumeration value="no-depends,size"/>
  97766. <xs:enumeration value="random"/>
  97767. <xs:enumeration value="reverse"/>
  97768. <xs:enumeration value="size"/>
  97769. </xs:restriction>
  97770. </xs:simpleType>
  97771. <xs:complexType name="fileFilterType">
  97772. <xs:simpleContent>
  97773. <xs:extension base="xs:anyURI">
  97774. <xs:attributeGroup ref="phpVersionGroup"/>
  97775. </xs:extension>
  97776. </xs:simpleContent>
  97777. </xs:complexType>
  97778. <xs:attributeGroup name="phpVersionGroup">
  97779. <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
  97780. <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
  97781. </xs:attributeGroup>
  97782. <xs:complexType name="phpType">
  97783. <xs:sequence>
  97784. <xs:choice maxOccurs="unbounded">
  97785. <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
  97786. <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97787. <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97788. <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97789. <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97790. <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97791. <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97792. <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97793. <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97794. <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97795. <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
  97796. </xs:choice>
  97797. </xs:sequence>
  97798. </xs:complexType>
  97799. <xs:complexType name="namedValueType">
  97800. <xs:attribute name="name" use="required" type="xs:string"/>
  97801. <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
  97802. <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
  97803. <xs:attribute name="force" use="optional" type="xs:boolean"/>
  97804. </xs:complexType>
  97805. <xs:complexType name="phpUnitType">
  97806. <xs:annotation>
  97807. <xs:documentation>The main type specifying the document structure</xs:documentation>
  97808. </xs:annotation>
  97809. <xs:group ref="configGroup"/>
  97810. <xs:attributeGroup ref="configAttributeGroup"/>
  97811. </xs:complexType>
  97812. <xs:attributeGroup name="configAttributeGroup">
  97813. <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
  97814. <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
  97815. <xs:attribute name="bootstrap" type="xs:anyURI"/>
  97816. <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
  97817. <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
  97818. <xs:attribute name="colors" type="xs:boolean" default="false"/>
  97819. <xs:attribute name="columns" type="columnsType" default="80"/>
  97820. <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="false"/>
  97821. <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
  97822. <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
  97823. <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
  97824. <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
  97825. <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
  97826. <xs:attribute name="printerFile" type="xs:anyURI"/>
  97827. <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
  97828. <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
  97829. <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
  97830. <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
  97831. <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
  97832. <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
  97833. <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
  97834. <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
  97835. <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
  97836. <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
  97837. <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
  97838. <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
  97839. <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
  97840. <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
  97841. <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
  97842. <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
  97843. <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
  97844. <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
  97845. <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
  97846. <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
  97847. <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
  97848. <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
  97849. <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
  97850. <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
  97851. <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
  97852. <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
  97853. <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
  97854. <xs:attribute name="verbose" type="xs:boolean" default="false"/>
  97855. <xs:attribute name="testdox" type="xs:boolean" default="false"/>
  97856. <xs:attribute name="stderr" type="xs:boolean" default="false"/>
  97857. <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
  97858. <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
  97859. <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
  97860. <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
  97861. <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
  97862. <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
  97863. </xs:attributeGroup>
  97864. <xs:group name="configGroup">
  97865. <xs:all>
  97866. <xs:element ref="testSuiteFacet" minOccurs="0"/>
  97867. <xs:element name="groups" type="groupsType" minOccurs="0"/>
  97868. <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
  97869. <xs:element name="coverage" type="coverageType" minOccurs="0"/>
  97870. <xs:element name="logging" type="loggingType" minOccurs="0"/>
  97871. <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
  97872. <xs:element name="listeners" type="listenersType" minOccurs="0"/>
  97873. <xs:element name="php" type="phpType" minOccurs="0"/>
  97874. </xs:all>
  97875. </xs:group>
  97876. <xs:element name="testSuiteFacet" abstract="true"/>
  97877. <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
  97878. <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
  97879. <xs:complexType name="testSuitesType">
  97880. <xs:sequence>
  97881. <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
  97882. </xs:sequence>
  97883. </xs:complexType>
  97884. <xs:complexType name="testSuiteType">
  97885. <xs:sequence>
  97886. <xs:choice minOccurs="0" maxOccurs="unbounded">
  97887. <xs:group ref="pathGroup"/>
  97888. <xs:element name="exclude" type="xs:string"/>
  97889. </xs:choice>
  97890. </xs:sequence>
  97891. <xs:attribute name="name" type="xs:string" use="required"/>
  97892. </xs:complexType>
  97893. <xs:group name="coverageReportGroup">
  97894. <xs:all>
  97895. <xs:element name="clover" type="logToFileType" minOccurs="0"/>
  97896. <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
  97897. <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
  97898. <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
  97899. <xs:element name="php" type="logToFileType" minOccurs="0" />
  97900. <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
  97901. <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
  97902. </xs:all>
  97903. </xs:group>
  97904. <xs:group name="loggingGroup">
  97905. <xs:all>
  97906. <xs:element name="junit" type="logToFileType" minOccurs="0" />
  97907. <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
  97908. <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
  97909. <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
  97910. <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
  97911. <xs:element name="text" type="logToFileType" minOccurs="0"/>
  97912. </xs:all>
  97913. </xs:group>
  97914. <xs:complexType name="logToFileType">
  97915. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97916. </xs:complexType>
  97917. <xs:complexType name="logToDirectoryType">
  97918. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97919. </xs:complexType>
  97920. <xs:complexType name="coverageReportCrap4JType">
  97921. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97922. <xs:attribute name="threshold" type="xs:integer"/>
  97923. </xs:complexType>
  97924. <xs:complexType name="coverageReportHtmlType">
  97925. <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
  97926. <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
  97927. <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
  97928. </xs:complexType>
  97929. <xs:complexType name="coverageReportTextType">
  97930. <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
  97931. <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
  97932. <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
  97933. </xs:complexType>
  97934. </xs:schema>
  97935. BSD 3-Clause License
  97936. Copyright (c) 2020-2024, Sebastian Bergmann
  97937. All rights reserved.
  97938. Redistribution and use in source and binary forms, with or without
  97939. modification, are permitted provided that the following conditions are met:
  97940. 1. Redistributions of source code must retain the above copyright notice, this
  97941. list of conditions and the following disclaimer.
  97942. 2. Redistributions in binary form must reproduce the above copyright notice,
  97943. this list of conditions and the following disclaimer in the documentation
  97944. and/or other materials provided with the distribution.
  97945. 3. Neither the name of the copyright holder nor the names of its
  97946. contributors may be used to endorse or promote products derived from
  97947. this software without specific prior written permission.
  97948. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  97949. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  97950. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  97951. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  97952. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  97953. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  97954. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  97955. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  97956. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  97957. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  97958. <?php
  97959. declare (strict_types=1);
  97960. /*
  97961. * This file is part of sebastian/cli-parser.
  97962. *
  97963. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  97964. *
  97965. * For the full copyright and license information, please view the LICENSE
  97966. * file that was distributed with this source code.
  97967. */
  97968. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  97969. use function array_map;
  97970. use function array_merge;
  97971. use function array_shift;
  97972. use function array_slice;
  97973. use function assert;
  97974. use function count;
  97975. use function current;
  97976. use function explode;
  97977. use function is_array;
  97978. use function is_int;
  97979. use function is_string;
  97980. use function key;
  97981. use function next;
  97982. use function preg_replace;
  97983. use function reset;
  97984. use function sort;
  97985. use function str_ends_with;
  97986. use function str_starts_with;
  97987. use function strlen;
  97988. use function strstr;
  97989. use function substr;
  97990. final class Parser
  97991. {
  97992. /**
  97993. * @psalm-param list<string> $argv
  97994. * @psalm-param list<string> $longOptions
  97995. *
  97996. * @psalm-return array{0: array, 1: array}
  97997. *
  97998. * @throws AmbiguousOptionException
  97999. * @throws OptionDoesNotAllowArgumentException
  98000. * @throws RequiredOptionArgumentMissingException
  98001. * @throws UnknownOptionException
  98002. */
  98003. public function parse(array $argv, string $shortOptions, ?array $longOptions = null): array
  98004. {
  98005. if (empty($argv)) {
  98006. return [[], []];
  98007. }
  98008. $options = [];
  98009. $nonOptions = [];
  98010. if ($longOptions) {
  98011. sort($longOptions);
  98012. }
  98013. if (isset($argv[0][0]) && $argv[0][0] !== '-') {
  98014. array_shift($argv);
  98015. }
  98016. reset($argv);
  98017. $argv = array_map('trim', $argv);
  98018. while (\false !== $arg = current($argv)) {
  98019. $i = key($argv);
  98020. assert(is_int($i));
  98021. next($argv);
  98022. if ($arg === '') {
  98023. continue;
  98024. }
  98025. if ($arg === '--') {
  98026. $nonOptions = array_merge($nonOptions, array_slice($argv, $i + 1));
  98027. break;
  98028. }
  98029. if ($arg[0] !== '-' || strlen($arg) > 1 && $arg[1] === '-' && !$longOptions) {
  98030. $nonOptions[] = $arg;
  98031. continue;
  98032. }
  98033. if (strlen($arg) > 1 && $arg[1] === '-' && is_array($longOptions)) {
  98034. $this->parseLongOption(substr($arg, 2), $longOptions, $options, $argv);
  98035. continue;
  98036. }
  98037. $this->parseShortOption(substr($arg, 1), $shortOptions, $options, $argv);
  98038. }
  98039. return [$options, $nonOptions];
  98040. }
  98041. /**
  98042. * @throws RequiredOptionArgumentMissingException
  98043. */
  98044. private function parseShortOption(string $argument, string $shortOptions, array &$options, array &$argv): void
  98045. {
  98046. $argumentLength = strlen($argument);
  98047. for ($i = 0; $i < $argumentLength; $i++) {
  98048. $option = $argument[$i];
  98049. $optionArgument = null;
  98050. if ($argument[$i] === ':' || ($spec = strstr($shortOptions, $option)) === \false) {
  98051. throw new UnknownOptionException('-' . $option);
  98052. }
  98053. if (strlen($spec) > 1 && $spec[1] === ':') {
  98054. if ($i + 1 < $argumentLength) {
  98055. $options[] = [$option, substr($argument, $i + 1)];
  98056. break;
  98057. }
  98058. if (!(strlen($spec) > 2 && $spec[2] === ':')) {
  98059. $optionArgument = current($argv);
  98060. if (!$optionArgument) {
  98061. throw new RequiredOptionArgumentMissingException('-' . $option);
  98062. }
  98063. assert(is_string($optionArgument));
  98064. next($argv);
  98065. }
  98066. }
  98067. $options[] = [$option, $optionArgument];
  98068. }
  98069. }
  98070. /**
  98071. * @psalm-param list<string> $longOptions
  98072. *
  98073. * @throws AmbiguousOptionException
  98074. * @throws OptionDoesNotAllowArgumentException
  98075. * @throws RequiredOptionArgumentMissingException
  98076. * @throws UnknownOptionException
  98077. */
  98078. private function parseLongOption(string $argument, array $longOptions, array &$options, array &$argv): void
  98079. {
  98080. $count = count($longOptions);
  98081. $list = explode('=', $argument);
  98082. $option = $list[0];
  98083. $optionArgument = null;
  98084. if (count($list) > 1) {
  98085. $optionArgument = $list[1];
  98086. }
  98087. $optionLength = strlen($option);
  98088. foreach ($longOptions as $i => $longOption) {
  98089. $opt_start = substr($longOption, 0, $optionLength);
  98090. if ($opt_start !== $option) {
  98091. continue;
  98092. }
  98093. $opt_rest = substr($longOption, $optionLength);
  98094. if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && str_starts_with($longOptions[$i + 1], $option)) {
  98095. throw new AmbiguousOptionException('--' . $option);
  98096. }
  98097. if (str_ends_with($longOption, '=')) {
  98098. if (!str_ends_with($longOption, '==') && !strlen((string) $optionArgument)) {
  98099. if (\false === $optionArgument = current($argv)) {
  98100. throw new RequiredOptionArgumentMissingException('--' . $option);
  98101. }
  98102. next($argv);
  98103. }
  98104. } elseif ($optionArgument) {
  98105. throw new OptionDoesNotAllowArgumentException('--' . $option);
  98106. }
  98107. $fullOption = '--' . preg_replace('/={1,2}$/', '', $longOption);
  98108. $options[] = [$fullOption, $optionArgument];
  98109. return;
  98110. }
  98111. throw new UnknownOptionException('--' . $option);
  98112. }
  98113. }
  98114. <?php
  98115. declare (strict_types=1);
  98116. /*
  98117. * This file is part of sebastian/cli-parser.
  98118. *
  98119. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98120. *
  98121. * For the full copyright and license information, please view the LICENSE
  98122. * file that was distributed with this source code.
  98123. */
  98124. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  98125. use function sprintf;
  98126. use RuntimeException;
  98127. final class AmbiguousOptionException extends RuntimeException implements Exception
  98128. {
  98129. public function __construct(string $option)
  98130. {
  98131. parent::__construct(sprintf('Option "%s" is ambiguous', $option));
  98132. }
  98133. }
  98134. <?php
  98135. declare (strict_types=1);
  98136. /*
  98137. * This file is part of sebastian/cli-parser.
  98138. *
  98139. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98140. *
  98141. * For the full copyright and license information, please view the LICENSE
  98142. * file that was distributed with this source code.
  98143. */
  98144. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  98145. use Throwable;
  98146. interface Exception extends Throwable
  98147. {
  98148. }
  98149. <?php
  98150. declare (strict_types=1);
  98151. /*
  98152. * This file is part of sebastian/cli-parser.
  98153. *
  98154. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98155. *
  98156. * For the full copyright and license information, please view the LICENSE
  98157. * file that was distributed with this source code.
  98158. */
  98159. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  98160. use function sprintf;
  98161. use RuntimeException;
  98162. final class OptionDoesNotAllowArgumentException extends RuntimeException implements Exception
  98163. {
  98164. public function __construct(string $option)
  98165. {
  98166. parent::__construct(sprintf('Option "%s" does not allow an argument', $option));
  98167. }
  98168. }
  98169. <?php
  98170. declare (strict_types=1);
  98171. /*
  98172. * This file is part of sebastian/cli-parser.
  98173. *
  98174. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98175. *
  98176. * For the full copyright and license information, please view the LICENSE
  98177. * file that was distributed with this source code.
  98178. */
  98179. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  98180. use function sprintf;
  98181. use RuntimeException;
  98182. final class RequiredOptionArgumentMissingException extends RuntimeException implements Exception
  98183. {
  98184. public function __construct(string $option)
  98185. {
  98186. parent::__construct(sprintf('Required argument for option "%s" is missing', $option));
  98187. }
  98188. }
  98189. <?php
  98190. declare (strict_types=1);
  98191. /*
  98192. * This file is part of sebastian/cli-parser.
  98193. *
  98194. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98195. *
  98196. * For the full copyright and license information, please view the LICENSE
  98197. * file that was distributed with this source code.
  98198. */
  98199. namespace PHPUnitPHAR\SebastianBergmann\CliParser;
  98200. use function sprintf;
  98201. use RuntimeException;
  98202. final class UnknownOptionException extends RuntimeException implements Exception
  98203. {
  98204. public function __construct(string $option)
  98205. {
  98206. parent::__construct(sprintf('Unknown option "%s"', $option));
  98207. }
  98208. }
  98209. BSD 3-Clause License
  98210. Copyright (c) 2016-2023, Sebastian Bergmann
  98211. All rights reserved.
  98212. Redistribution and use in source and binary forms, with or without
  98213. modification, are permitted provided that the following conditions are met:
  98214. 1. Redistributions of source code must retain the above copyright notice, this
  98215. list of conditions and the following disclaimer.
  98216. 2. Redistributions in binary form must reproduce the above copyright notice,
  98217. this list of conditions and the following disclaimer in the documentation
  98218. and/or other materials provided with the distribution.
  98219. 3. Neither the name of the copyright holder nor the names of its
  98220. contributors may be used to endorse or promote products derived from
  98221. this software without specific prior written permission.
  98222. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  98223. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  98224. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  98225. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  98226. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  98227. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  98228. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  98229. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  98230. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  98231. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  98232. <?php
  98233. declare (strict_types=1);
  98234. /*
  98235. * This file is part of sebastian/code-unit-reverse-lookup.
  98236. *
  98237. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98238. *
  98239. * For the full copyright and license information, please view the LICENSE
  98240. * file that was distributed with this source code.
  98241. */
  98242. namespace PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup;
  98243. use function array_merge;
  98244. use function assert;
  98245. use function get_declared_classes;
  98246. use function get_declared_traits;
  98247. use function get_defined_functions;
  98248. use function is_array;
  98249. use function range;
  98250. use ReflectionClass;
  98251. use ReflectionFunction;
  98252. use ReflectionFunctionAbstract;
  98253. use ReflectionMethod;
  98254. class Wizard
  98255. {
  98256. /**
  98257. * @psalm-var array<string,array<int,string>>
  98258. */
  98259. private array $lookupTable = [];
  98260. /**
  98261. * @psalm-var array<class-string,true>
  98262. */
  98263. private array $processedClasses = [];
  98264. /**
  98265. * @psalm-var array<string,true>
  98266. */
  98267. private array $processedFunctions = [];
  98268. public function lookup(string $filename, int $lineNumber): string
  98269. {
  98270. if (!isset($this->lookupTable[$filename][$lineNumber])) {
  98271. $this->updateLookupTable();
  98272. }
  98273. if (isset($this->lookupTable[$filename][$lineNumber])) {
  98274. return $this->lookupTable[$filename][$lineNumber];
  98275. }
  98276. return $filename . ':' . $lineNumber;
  98277. }
  98278. private function updateLookupTable(): void
  98279. {
  98280. $this->processClassesAndTraits();
  98281. $this->processFunctions();
  98282. }
  98283. private function processClassesAndTraits(): void
  98284. {
  98285. $classes = get_declared_classes();
  98286. $traits = get_declared_traits();
  98287. /* @noinspection PhpConditionAlreadyCheckedInspection */
  98288. assert(is_array($traits));
  98289. foreach (array_merge($classes, $traits) as $classOrTrait) {
  98290. if (isset($this->processedClasses[$classOrTrait])) {
  98291. continue;
  98292. }
  98293. foreach ((new ReflectionClass($classOrTrait))->getMethods() as $method) {
  98294. $this->processFunctionOrMethod($method);
  98295. }
  98296. $this->processedClasses[$classOrTrait] = \true;
  98297. }
  98298. }
  98299. private function processFunctions(): void
  98300. {
  98301. foreach (get_defined_functions()['user'] as $function) {
  98302. if (isset($this->processedFunctions[$function])) {
  98303. continue;
  98304. }
  98305. $this->processFunctionOrMethod(new ReflectionFunction($function));
  98306. $this->processedFunctions[$function] = \true;
  98307. }
  98308. }
  98309. private function processFunctionOrMethod(ReflectionFunctionAbstract $functionOrMethod): void
  98310. {
  98311. if ($functionOrMethod->isInternal()) {
  98312. return;
  98313. }
  98314. $name = $functionOrMethod->getName();
  98315. if ($functionOrMethod instanceof ReflectionMethod) {
  98316. $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name;
  98317. }
  98318. if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) {
  98319. $this->lookupTable[$functionOrMethod->getFileName()] = [];
  98320. }
  98321. foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) {
  98322. $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name;
  98323. }
  98324. }
  98325. }
  98326. <?php
  98327. declare (strict_types=1);
  98328. /*
  98329. * This file is part of sebastian/code-unit.
  98330. *
  98331. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98332. *
  98333. * For the full copyright and license information, please view the LICENSE
  98334. * file that was distributed with this source code.
  98335. */
  98336. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98337. /**
  98338. * @psalm-immutable
  98339. */
  98340. final class ClassMethodUnit extends CodeUnit
  98341. {
  98342. /**
  98343. * @psalm-assert-if-true ClassMethodUnit $this
  98344. */
  98345. public function isClassMethod(): bool
  98346. {
  98347. return \true;
  98348. }
  98349. }
  98350. <?php
  98351. declare (strict_types=1);
  98352. /*
  98353. * This file is part of sebastian/code-unit.
  98354. *
  98355. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98356. *
  98357. * For the full copyright and license information, please view the LICENSE
  98358. * file that was distributed with this source code.
  98359. */
  98360. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98361. /**
  98362. * @psalm-immutable
  98363. */
  98364. final class ClassUnit extends CodeUnit
  98365. {
  98366. /**
  98367. * @psalm-assert-if-true ClassUnit $this
  98368. */
  98369. public function isClass(): bool
  98370. {
  98371. return \true;
  98372. }
  98373. }
  98374. <?php
  98375. declare (strict_types=1);
  98376. /*
  98377. * This file is part of sebastian/code-unit.
  98378. *
  98379. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98380. *
  98381. * For the full copyright and license information, please view the LICENSE
  98382. * file that was distributed with this source code.
  98383. */
  98384. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98385. use function count;
  98386. use function file;
  98387. use function file_exists;
  98388. use function is_readable;
  98389. use function range;
  98390. use function sprintf;
  98391. use ReflectionClass;
  98392. use ReflectionFunction;
  98393. use ReflectionMethod;
  98394. /**
  98395. * @psalm-immutable
  98396. */
  98397. abstract class CodeUnit
  98398. {
  98399. private readonly string $name;
  98400. private readonly string $sourceFileName;
  98401. /**
  98402. * @psalm-var list<int>
  98403. */
  98404. private readonly array $sourceLines;
  98405. /**
  98406. * @psalm-param class-string $className
  98407. *
  98408. * @throws InvalidCodeUnitException
  98409. * @throws ReflectionException
  98410. */
  98411. public static function forClass(string $className): ClassUnit
  98412. {
  98413. self::ensureUserDefinedClass($className);
  98414. $reflector = self::reflectorForClass($className);
  98415. return new ClassUnit($className, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98416. }
  98417. /**
  98418. * @psalm-param class-string $className
  98419. *
  98420. * @throws InvalidCodeUnitException
  98421. * @throws ReflectionException
  98422. */
  98423. public static function forClassMethod(string $className, string $methodName): ClassMethodUnit
  98424. {
  98425. self::ensureUserDefinedClass($className);
  98426. $reflector = self::reflectorForClassMethod($className, $methodName);
  98427. return new ClassMethodUnit($className . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98428. }
  98429. /**
  98430. * @throws InvalidCodeUnitException
  98431. */
  98432. public static function forFileWithAbsolutePath(string $path): FileUnit
  98433. {
  98434. self::ensureFileExistsAndIsReadable($path);
  98435. return new FileUnit($path, $path, range(1, count(file($path))));
  98436. }
  98437. /**
  98438. * @psalm-param class-string $interfaceName
  98439. *
  98440. * @throws InvalidCodeUnitException
  98441. * @throws ReflectionException
  98442. */
  98443. public static function forInterface(string $interfaceName): InterfaceUnit
  98444. {
  98445. self::ensureUserDefinedInterface($interfaceName);
  98446. $reflector = self::reflectorForClass($interfaceName);
  98447. return new InterfaceUnit($interfaceName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98448. }
  98449. /**
  98450. * @psalm-param class-string $interfaceName
  98451. *
  98452. * @throws InvalidCodeUnitException
  98453. * @throws ReflectionException
  98454. */
  98455. public static function forInterfaceMethod(string $interfaceName, string $methodName): InterfaceMethodUnit
  98456. {
  98457. self::ensureUserDefinedInterface($interfaceName);
  98458. $reflector = self::reflectorForClassMethod($interfaceName, $methodName);
  98459. return new InterfaceMethodUnit($interfaceName . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98460. }
  98461. /**
  98462. * @psalm-param class-string $traitName
  98463. *
  98464. * @throws InvalidCodeUnitException
  98465. * @throws ReflectionException
  98466. */
  98467. public static function forTrait(string $traitName): TraitUnit
  98468. {
  98469. self::ensureUserDefinedTrait($traitName);
  98470. $reflector = self::reflectorForClass($traitName);
  98471. return new TraitUnit($traitName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98472. }
  98473. /**
  98474. * @psalm-param class-string $traitName
  98475. *
  98476. * @throws InvalidCodeUnitException
  98477. * @throws ReflectionException
  98478. */
  98479. public static function forTraitMethod(string $traitName, string $methodName): TraitMethodUnit
  98480. {
  98481. self::ensureUserDefinedTrait($traitName);
  98482. $reflector = self::reflectorForClassMethod($traitName, $methodName);
  98483. return new TraitMethodUnit($traitName . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98484. }
  98485. /**
  98486. * @psalm-param callable-string $functionName
  98487. *
  98488. * @throws InvalidCodeUnitException
  98489. * @throws ReflectionException
  98490. */
  98491. public static function forFunction(string $functionName): FunctionUnit
  98492. {
  98493. $reflector = self::reflectorForFunction($functionName);
  98494. if (!$reflector->isUserDefined()) {
  98495. throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined function', $functionName));
  98496. }
  98497. return new FunctionUnit($functionName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
  98498. }
  98499. /**
  98500. * @psalm-param list<int> $sourceLines
  98501. */
  98502. private function __construct(string $name, string $sourceFileName, array $sourceLines)
  98503. {
  98504. $this->name = $name;
  98505. $this->sourceFileName = $sourceFileName;
  98506. $this->sourceLines = $sourceLines;
  98507. }
  98508. public function name(): string
  98509. {
  98510. return $this->name;
  98511. }
  98512. public function sourceFileName(): string
  98513. {
  98514. return $this->sourceFileName;
  98515. }
  98516. /**
  98517. * @psalm-return list<int>
  98518. */
  98519. public function sourceLines(): array
  98520. {
  98521. return $this->sourceLines;
  98522. }
  98523. public function isClass(): bool
  98524. {
  98525. return \false;
  98526. }
  98527. public function isClassMethod(): bool
  98528. {
  98529. return \false;
  98530. }
  98531. public function isInterface(): bool
  98532. {
  98533. return \false;
  98534. }
  98535. public function isInterfaceMethod(): bool
  98536. {
  98537. return \false;
  98538. }
  98539. public function isTrait(): bool
  98540. {
  98541. return \false;
  98542. }
  98543. public function isTraitMethod(): bool
  98544. {
  98545. return \false;
  98546. }
  98547. public function isFunction(): bool
  98548. {
  98549. return \false;
  98550. }
  98551. public function isFile(): bool
  98552. {
  98553. return \false;
  98554. }
  98555. /**
  98556. * @throws InvalidCodeUnitException
  98557. */
  98558. private static function ensureFileExistsAndIsReadable(string $path): void
  98559. {
  98560. if (!(file_exists($path) && is_readable($path))) {
  98561. throw new InvalidCodeUnitException(sprintf('File "%s" does not exist or is not readable', $path));
  98562. }
  98563. }
  98564. /**
  98565. * @psalm-param class-string $className
  98566. *
  98567. * @throws InvalidCodeUnitException
  98568. */
  98569. private static function ensureUserDefinedClass(string $className): void
  98570. {
  98571. try {
  98572. $reflector = new ReflectionClass($className);
  98573. if ($reflector->isInterface()) {
  98574. throw new InvalidCodeUnitException(sprintf('"%s" is an interface and not a class', $className));
  98575. }
  98576. if ($reflector->isTrait()) {
  98577. throw new InvalidCodeUnitException(sprintf('"%s" is a trait and not a class', $className));
  98578. }
  98579. if (!$reflector->isUserDefined()) {
  98580. throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined class', $className));
  98581. }
  98582. // @codeCoverageIgnoreStart
  98583. } catch (\ReflectionException $e) {
  98584. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98585. }
  98586. // @codeCoverageIgnoreEnd
  98587. }
  98588. /**
  98589. * @psalm-param class-string $interfaceName
  98590. *
  98591. * @throws InvalidCodeUnitException
  98592. */
  98593. private static function ensureUserDefinedInterface(string $interfaceName): void
  98594. {
  98595. try {
  98596. $reflector = new ReflectionClass($interfaceName);
  98597. if (!$reflector->isInterface()) {
  98598. throw new InvalidCodeUnitException(sprintf('"%s" is not an interface', $interfaceName));
  98599. }
  98600. if (!$reflector->isUserDefined()) {
  98601. throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined interface', $interfaceName));
  98602. }
  98603. // @codeCoverageIgnoreStart
  98604. } catch (\ReflectionException $e) {
  98605. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98606. }
  98607. // @codeCoverageIgnoreEnd
  98608. }
  98609. /**
  98610. * @psalm-param class-string $traitName
  98611. *
  98612. * @throws InvalidCodeUnitException
  98613. */
  98614. private static function ensureUserDefinedTrait(string $traitName): void
  98615. {
  98616. try {
  98617. $reflector = new ReflectionClass($traitName);
  98618. if (!$reflector->isTrait()) {
  98619. throw new InvalidCodeUnitException(sprintf('"%s" is not a trait', $traitName));
  98620. }
  98621. // @codeCoverageIgnoreStart
  98622. if (!$reflector->isUserDefined()) {
  98623. throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined trait', $traitName));
  98624. }
  98625. } catch (\ReflectionException $e) {
  98626. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98627. }
  98628. // @codeCoverageIgnoreEnd
  98629. }
  98630. /**
  98631. * @psalm-param class-string $className
  98632. *
  98633. * @throws ReflectionException
  98634. */
  98635. private static function reflectorForClass(string $className): ReflectionClass
  98636. {
  98637. try {
  98638. return new ReflectionClass($className);
  98639. // @codeCoverageIgnoreStart
  98640. } catch (\ReflectionException $e) {
  98641. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98642. }
  98643. // @codeCoverageIgnoreEnd
  98644. }
  98645. /**
  98646. * @psalm-param class-string $className
  98647. *
  98648. * @throws ReflectionException
  98649. */
  98650. private static function reflectorForClassMethod(string $className, string $methodName): ReflectionMethod
  98651. {
  98652. try {
  98653. return new ReflectionMethod($className, $methodName);
  98654. // @codeCoverageIgnoreStart
  98655. } catch (\ReflectionException $e) {
  98656. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98657. }
  98658. // @codeCoverageIgnoreEnd
  98659. }
  98660. /**
  98661. * @psalm-param callable-string $functionName
  98662. *
  98663. * @throws ReflectionException
  98664. */
  98665. private static function reflectorForFunction(string $functionName): ReflectionFunction
  98666. {
  98667. try {
  98668. return new ReflectionFunction($functionName);
  98669. // @codeCoverageIgnoreStart
  98670. } catch (\ReflectionException $e) {
  98671. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  98672. }
  98673. // @codeCoverageIgnoreEnd
  98674. }
  98675. }
  98676. <?php
  98677. declare (strict_types=1);
  98678. /*
  98679. * This file is part of sebastian/code-unit.
  98680. *
  98681. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98682. *
  98683. * For the full copyright and license information, please view the LICENSE
  98684. * file that was distributed with this source code.
  98685. */
  98686. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98687. use function array_merge;
  98688. use function count;
  98689. use Countable;
  98690. use IteratorAggregate;
  98691. /**
  98692. * @template-implements IteratorAggregate<int, CodeUnit>
  98693. *
  98694. * @psalm-immutable
  98695. */
  98696. final class CodeUnitCollection implements Countable, IteratorAggregate
  98697. {
  98698. /**
  98699. * @psalm-var list<CodeUnit>
  98700. */
  98701. private readonly array $codeUnits;
  98702. public static function fromList(CodeUnit ...$codeUnits): self
  98703. {
  98704. return new self($codeUnits);
  98705. }
  98706. /**
  98707. * @psalm-param list<CodeUnit> $codeUnits
  98708. */
  98709. private function __construct(array $codeUnits)
  98710. {
  98711. $this->codeUnits = $codeUnits;
  98712. }
  98713. /**
  98714. * @psalm-return list<CodeUnit>
  98715. */
  98716. public function asArray(): array
  98717. {
  98718. return $this->codeUnits;
  98719. }
  98720. public function getIterator(): CodeUnitCollectionIterator
  98721. {
  98722. return new CodeUnitCollectionIterator($this);
  98723. }
  98724. public function count(): int
  98725. {
  98726. return count($this->codeUnits);
  98727. }
  98728. public function isEmpty(): bool
  98729. {
  98730. return empty($this->codeUnits);
  98731. }
  98732. public function mergeWith(self $other): self
  98733. {
  98734. return new self(array_merge($this->asArray(), $other->asArray()));
  98735. }
  98736. }
  98737. <?php
  98738. declare (strict_types=1);
  98739. /*
  98740. * This file is part of sebastian/code-unit.
  98741. *
  98742. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98743. *
  98744. * For the full copyright and license information, please view the LICENSE
  98745. * file that was distributed with this source code.
  98746. */
  98747. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98748. use Iterator;
  98749. /**
  98750. * @template-implements Iterator<int, CodeUnit>
  98751. */
  98752. final class CodeUnitCollectionIterator implements Iterator
  98753. {
  98754. /**
  98755. * @psalm-var list<CodeUnit>
  98756. */
  98757. private array $codeUnits;
  98758. private int $position = 0;
  98759. public function __construct(CodeUnitCollection $collection)
  98760. {
  98761. $this->codeUnits = $collection->asArray();
  98762. }
  98763. public function rewind(): void
  98764. {
  98765. $this->position = 0;
  98766. }
  98767. public function valid(): bool
  98768. {
  98769. return isset($this->codeUnits[$this->position]);
  98770. }
  98771. public function key(): int
  98772. {
  98773. return $this->position;
  98774. }
  98775. public function current(): CodeUnit
  98776. {
  98777. return $this->codeUnits[$this->position];
  98778. }
  98779. public function next(): void
  98780. {
  98781. $this->position++;
  98782. }
  98783. }
  98784. <?php
  98785. declare (strict_types=1);
  98786. /*
  98787. * This file is part of sebastian/code-unit.
  98788. *
  98789. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98790. *
  98791. * For the full copyright and license information, please view the LICENSE
  98792. * file that was distributed with this source code.
  98793. */
  98794. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98795. /**
  98796. * @psalm-immutable
  98797. */
  98798. final class FileUnit extends CodeUnit
  98799. {
  98800. /**
  98801. * @psalm-assert-if-true FileUnit $this
  98802. */
  98803. public function isFile(): bool
  98804. {
  98805. return \true;
  98806. }
  98807. }
  98808. <?php
  98809. declare (strict_types=1);
  98810. /*
  98811. * This file is part of sebastian/code-unit.
  98812. *
  98813. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98814. *
  98815. * For the full copyright and license information, please view the LICENSE
  98816. * file that was distributed with this source code.
  98817. */
  98818. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98819. /**
  98820. * @psalm-immutable
  98821. */
  98822. final class FunctionUnit extends CodeUnit
  98823. {
  98824. /**
  98825. * @psalm-assert-if-true FunctionUnit $this
  98826. */
  98827. public function isFunction(): bool
  98828. {
  98829. return \true;
  98830. }
  98831. }
  98832. <?php
  98833. declare (strict_types=1);
  98834. /*
  98835. * This file is part of sebastian/code-unit.
  98836. *
  98837. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98838. *
  98839. * For the full copyright and license information, please view the LICENSE
  98840. * file that was distributed with this source code.
  98841. */
  98842. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98843. /**
  98844. * @psalm-immutable
  98845. */
  98846. final class InterfaceMethodUnit extends CodeUnit
  98847. {
  98848. /**
  98849. * @psalm-assert-if-true InterfaceMethod $this
  98850. */
  98851. public function isInterfaceMethod(): bool
  98852. {
  98853. return \true;
  98854. }
  98855. }
  98856. <?php
  98857. declare (strict_types=1);
  98858. /*
  98859. * This file is part of sebastian/code-unit.
  98860. *
  98861. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98862. *
  98863. * For the full copyright and license information, please view the LICENSE
  98864. * file that was distributed with this source code.
  98865. */
  98866. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98867. /**
  98868. * @psalm-immutable
  98869. */
  98870. final class InterfaceUnit extends CodeUnit
  98871. {
  98872. /**
  98873. * @psalm-assert-if-true InterfaceUnit $this
  98874. */
  98875. public function isInterface(): bool
  98876. {
  98877. return \true;
  98878. }
  98879. }
  98880. BSD 3-Clause License
  98881. Copyright (c) 2020-2023, Sebastian Bergmann
  98882. All rights reserved.
  98883. Redistribution and use in source and binary forms, with or without
  98884. modification, are permitted provided that the following conditions are met:
  98885. 1. Redistributions of source code must retain the above copyright notice, this
  98886. list of conditions and the following disclaimer.
  98887. 2. Redistributions in binary form must reproduce the above copyright notice,
  98888. this list of conditions and the following disclaimer in the documentation
  98889. and/or other materials provided with the distribution.
  98890. 3. Neither the name of the copyright holder nor the names of its
  98891. contributors may be used to endorse or promote products derived from
  98892. this software without specific prior written permission.
  98893. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  98894. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  98895. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  98896. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  98897. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  98898. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  98899. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  98900. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  98901. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  98902. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  98903. <?php
  98904. declare (strict_types=1);
  98905. /*
  98906. * This file is part of sebastian/code-unit.
  98907. *
  98908. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  98909. *
  98910. * For the full copyright and license information, please view the LICENSE
  98911. * file that was distributed with this source code.
  98912. */
  98913. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  98914. use function array_keys;
  98915. use function array_merge;
  98916. use function array_unique;
  98917. use function array_values;
  98918. use function class_exists;
  98919. use function explode;
  98920. use function function_exists;
  98921. use function interface_exists;
  98922. use function ksort;
  98923. use function method_exists;
  98924. use function sort;
  98925. use function sprintf;
  98926. use function str_contains;
  98927. use function trait_exists;
  98928. use ReflectionClass;
  98929. use ReflectionFunction;
  98930. use ReflectionMethod;
  98931. final class Mapper
  98932. {
  98933. /**
  98934. * @psalm-return array<string,list<int>>
  98935. */
  98936. public function codeUnitsToSourceLines(CodeUnitCollection $codeUnits): array
  98937. {
  98938. $result = [];
  98939. foreach ($codeUnits as $codeUnit) {
  98940. $sourceFileName = $codeUnit->sourceFileName();
  98941. if (!isset($result[$sourceFileName])) {
  98942. $result[$sourceFileName] = [];
  98943. }
  98944. $result[$sourceFileName] = array_merge($result[$sourceFileName], $codeUnit->sourceLines());
  98945. }
  98946. foreach (array_keys($result) as $sourceFileName) {
  98947. $result[$sourceFileName] = array_values(array_unique($result[$sourceFileName]));
  98948. sort($result[$sourceFileName]);
  98949. }
  98950. ksort($result);
  98951. return $result;
  98952. }
  98953. /**
  98954. * @throws InvalidCodeUnitException
  98955. * @throws ReflectionException
  98956. */
  98957. public function stringToCodeUnits(string $unit): CodeUnitCollection
  98958. {
  98959. if (str_contains($unit, '::')) {
  98960. [$firstPart, $secondPart] = explode('::', $unit);
  98961. if ($this->isUserDefinedFunction($secondPart)) {
  98962. return CodeUnitCollection::fromList(CodeUnit::forFunction($secondPart));
  98963. }
  98964. if ($this->isUserDefinedMethod($firstPart, $secondPart)) {
  98965. return CodeUnitCollection::fromList(CodeUnit::forClassMethod($firstPart, $secondPart));
  98966. }
  98967. if ($this->isUserDefinedInterface($firstPart)) {
  98968. return CodeUnitCollection::fromList(CodeUnit::forInterfaceMethod($firstPart, $secondPart));
  98969. }
  98970. if ($this->isUserDefinedTrait($firstPart)) {
  98971. return CodeUnitCollection::fromList(CodeUnit::forTraitMethod($firstPart, $secondPart));
  98972. }
  98973. } else {
  98974. if ($this->isUserDefinedClass($unit)) {
  98975. $units = [CodeUnit::forClass($unit)];
  98976. foreach ($this->reflectorForClass($unit)->getTraits() as $trait) {
  98977. if (!$trait->isUserDefined()) {
  98978. // @codeCoverageIgnoreStart
  98979. continue;
  98980. // @codeCoverageIgnoreEnd
  98981. }
  98982. $units[] = CodeUnit::forTrait($trait->getName());
  98983. }
  98984. return CodeUnitCollection::fromList(...$units);
  98985. }
  98986. if ($this->isUserDefinedInterface($unit)) {
  98987. return CodeUnitCollection::fromList(CodeUnit::forInterface($unit));
  98988. }
  98989. if ($this->isUserDefinedTrait($unit)) {
  98990. return CodeUnitCollection::fromList(CodeUnit::forTrait($unit));
  98991. }
  98992. if ($this->isUserDefinedFunction($unit)) {
  98993. return CodeUnitCollection::fromList(CodeUnit::forFunction($unit));
  98994. }
  98995. }
  98996. throw new InvalidCodeUnitException(sprintf('"%s" is not a valid code unit', $unit));
  98997. }
  98998. /**
  98999. * @psalm-param class-string $className
  99000. *
  99001. * @throws ReflectionException
  99002. */
  99003. private function reflectorForClass(string $className): ReflectionClass
  99004. {
  99005. try {
  99006. return new ReflectionClass($className);
  99007. // @codeCoverageIgnoreStart
  99008. } catch (\ReflectionException $e) {
  99009. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99010. }
  99011. // @codeCoverageIgnoreEnd
  99012. }
  99013. /**
  99014. * @throws ReflectionException
  99015. */
  99016. private function isUserDefinedFunction(string $functionName): bool
  99017. {
  99018. if (!function_exists($functionName)) {
  99019. return \false;
  99020. }
  99021. try {
  99022. return (new ReflectionFunction($functionName))->isUserDefined();
  99023. // @codeCoverageIgnoreStart
  99024. } catch (\ReflectionException $e) {
  99025. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99026. }
  99027. // @codeCoverageIgnoreEnd
  99028. }
  99029. /**
  99030. * @throws ReflectionException
  99031. */
  99032. private function isUserDefinedClass(string $className): bool
  99033. {
  99034. if (!class_exists($className)) {
  99035. return \false;
  99036. }
  99037. try {
  99038. return (new ReflectionClass($className))->isUserDefined();
  99039. // @codeCoverageIgnoreStart
  99040. } catch (\ReflectionException $e) {
  99041. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99042. }
  99043. // @codeCoverageIgnoreEnd
  99044. }
  99045. /**
  99046. * @throws ReflectionException
  99047. */
  99048. private function isUserDefinedInterface(string $interfaceName): bool
  99049. {
  99050. if (!interface_exists($interfaceName)) {
  99051. return \false;
  99052. }
  99053. try {
  99054. return (new ReflectionClass($interfaceName))->isUserDefined();
  99055. // @codeCoverageIgnoreStart
  99056. } catch (\ReflectionException $e) {
  99057. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99058. }
  99059. // @codeCoverageIgnoreEnd
  99060. }
  99061. /**
  99062. * @throws ReflectionException
  99063. */
  99064. private function isUserDefinedTrait(string $traitName): bool
  99065. {
  99066. if (!trait_exists($traitName)) {
  99067. return \false;
  99068. }
  99069. try {
  99070. return (new ReflectionClass($traitName))->isUserDefined();
  99071. // @codeCoverageIgnoreStart
  99072. } catch (\ReflectionException $e) {
  99073. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99074. }
  99075. // @codeCoverageIgnoreEnd
  99076. }
  99077. /**
  99078. * @throws ReflectionException
  99079. */
  99080. private function isUserDefinedMethod(string $className, string $methodName): bool
  99081. {
  99082. if (!class_exists($className)) {
  99083. // @codeCoverageIgnoreStart
  99084. return \false;
  99085. // @codeCoverageIgnoreEnd
  99086. }
  99087. if (!method_exists($className, $methodName)) {
  99088. // @codeCoverageIgnoreStart
  99089. return \false;
  99090. // @codeCoverageIgnoreEnd
  99091. }
  99092. try {
  99093. return (new ReflectionMethod($className, $methodName))->isUserDefined();
  99094. // @codeCoverageIgnoreStart
  99095. } catch (\ReflectionException $e) {
  99096. throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
  99097. }
  99098. // @codeCoverageIgnoreEnd
  99099. }
  99100. }
  99101. <?php
  99102. declare (strict_types=1);
  99103. /*
  99104. * This file is part of sebastian/code-unit.
  99105. *
  99106. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99107. *
  99108. * For the full copyright and license information, please view the LICENSE
  99109. * file that was distributed with this source code.
  99110. */
  99111. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99112. /**
  99113. * @psalm-immutable
  99114. */
  99115. final class TraitMethodUnit extends CodeUnit
  99116. {
  99117. /**
  99118. * @psalm-assert-if-true TraitMethodUnit $this
  99119. */
  99120. public function isTraitMethod(): bool
  99121. {
  99122. return \true;
  99123. }
  99124. }
  99125. <?php
  99126. declare (strict_types=1);
  99127. /*
  99128. * This file is part of sebastian/code-unit.
  99129. *
  99130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99131. *
  99132. * For the full copyright and license information, please view the LICENSE
  99133. * file that was distributed with this source code.
  99134. */
  99135. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99136. /**
  99137. * @psalm-immutable
  99138. */
  99139. final class TraitUnit extends CodeUnit
  99140. {
  99141. /**
  99142. * @psalm-assert-if-true TraitUnit $this
  99143. */
  99144. public function isTrait(): bool
  99145. {
  99146. return \true;
  99147. }
  99148. }
  99149. <?php
  99150. declare (strict_types=1);
  99151. /*
  99152. * This file is part of sebastian/code-unit.
  99153. *
  99154. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99155. *
  99156. * For the full copyright and license information, please view the LICENSE
  99157. * file that was distributed with this source code.
  99158. */
  99159. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99160. use Throwable;
  99161. interface Exception extends Throwable
  99162. {
  99163. }
  99164. <?php
  99165. declare (strict_types=1);
  99166. /*
  99167. * This file is part of sebastian/code-unit.
  99168. *
  99169. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99170. *
  99171. * For the full copyright and license information, please view the LICENSE
  99172. * file that was distributed with this source code.
  99173. */
  99174. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99175. use RuntimeException;
  99176. final class InvalidCodeUnitException extends RuntimeException implements Exception
  99177. {
  99178. }
  99179. <?php
  99180. declare (strict_types=1);
  99181. /*
  99182. * This file is part of sebastian/code-unit.
  99183. *
  99184. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99185. *
  99186. * For the full copyright and license information, please view the LICENSE
  99187. * file that was distributed with this source code.
  99188. */
  99189. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99190. use RuntimeException;
  99191. final class NoTraitException extends RuntimeException implements Exception
  99192. {
  99193. }
  99194. <?php
  99195. declare (strict_types=1);
  99196. /*
  99197. * This file is part of sebastian/code-unit.
  99198. *
  99199. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99200. *
  99201. * For the full copyright and license information, please view the LICENSE
  99202. * file that was distributed with this source code.
  99203. */
  99204. namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
  99205. use RuntimeException;
  99206. final class ReflectionException extends RuntimeException implements Exception
  99207. {
  99208. }
  99209. <?php
  99210. declare (strict_types=1);
  99211. /*
  99212. * This file is part of sebastian/comparator.
  99213. *
  99214. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99215. *
  99216. * For the full copyright and license information, please view the LICENSE
  99217. * file that was distributed with this source code.
  99218. */
  99219. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99220. use function array_key_exists;
  99221. use function assert;
  99222. use function is_array;
  99223. use function sort;
  99224. use function sprintf;
  99225. use function str_replace;
  99226. use function trim;
  99227. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99228. /**
  99229. * Arrays are equal if they contain the same key-value pairs.
  99230. * The order of the keys does not matter.
  99231. * The types of key-value pairs do not matter.
  99232. */
  99233. class ArrayComparator extends Comparator
  99234. {
  99235. public function accepts(mixed $expected, mixed $actual): bool
  99236. {
  99237. return is_array($expected) && is_array($actual);
  99238. }
  99239. /**
  99240. * @throws ComparisonFailure
  99241. */
  99242. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
  99243. {
  99244. assert(is_array($expected));
  99245. assert(is_array($actual));
  99246. if ($canonicalize) {
  99247. sort($expected);
  99248. sort($actual);
  99249. }
  99250. $remaining = $actual;
  99251. $actualAsString = "Array (\n";
  99252. $expectedAsString = "Array (\n";
  99253. $equal = \true;
  99254. $exporter = new Exporter();
  99255. foreach ($expected as $key => $value) {
  99256. unset($remaining[$key]);
  99257. if (!array_key_exists($key, $actual)) {
  99258. $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
  99259. $equal = \false;
  99260. continue;
  99261. }
  99262. try {
  99263. $comparator = $this->factory()->getComparatorFor($value, $actual[$key]);
  99264. $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
  99265. $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
  99266. $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($actual[$key]));
  99267. } catch (ComparisonFailure $e) {
  99268. $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $exporter->shortenedExport($e->getExpected()));
  99269. $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $e->getActualAsString() ? $this->indent($e->getActualAsString()) : $exporter->shortenedExport($e->getActual()));
  99270. $equal = \false;
  99271. }
  99272. }
  99273. foreach ($remaining as $key => $value) {
  99274. $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
  99275. $equal = \false;
  99276. }
  99277. $expectedAsString .= ')';
  99278. $actualAsString .= ')';
  99279. if (!$equal) {
  99280. throw new ComparisonFailure($expected, $actual, $expectedAsString, $actualAsString, 'Failed asserting that two arrays are equal.');
  99281. }
  99282. }
  99283. private function indent(string $lines): string
  99284. {
  99285. return trim(str_replace("\n", "\n ", $lines));
  99286. }
  99287. }
  99288. <?php
  99289. declare (strict_types=1);
  99290. /*
  99291. * This file is part of sebastian/comparator.
  99292. *
  99293. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99294. *
  99295. * For the full copyright and license information, please view the LICENSE
  99296. * file that was distributed with this source code.
  99297. */
  99298. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99299. abstract class Comparator
  99300. {
  99301. private Factory $factory;
  99302. public function setFactory(Factory $factory): void
  99303. {
  99304. $this->factory = $factory;
  99305. }
  99306. abstract public function accepts(mixed $expected, mixed $actual): bool;
  99307. /**
  99308. * @throws ComparisonFailure
  99309. */
  99310. abstract public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void;
  99311. protected function factory(): Factory
  99312. {
  99313. return $this->factory;
  99314. }
  99315. }
  99316. <?php
  99317. declare (strict_types=1);
  99318. /*
  99319. * This file is part of sebastian/comparator.
  99320. *
  99321. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99322. *
  99323. * For the full copyright and license information, please view the LICENSE
  99324. * file that was distributed with this source code.
  99325. */
  99326. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99327. use RuntimeException;
  99328. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  99329. use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
  99330. final class ComparisonFailure extends RuntimeException
  99331. {
  99332. private mixed $expected;
  99333. private mixed $actual;
  99334. private string $expectedAsString;
  99335. private string $actualAsString;
  99336. public function __construct(mixed $expected, mixed $actual, string $expectedAsString, string $actualAsString, string $message = '')
  99337. {
  99338. parent::__construct($message);
  99339. $this->expected = $expected;
  99340. $this->actual = $actual;
  99341. $this->expectedAsString = $expectedAsString;
  99342. $this->actualAsString = $actualAsString;
  99343. }
  99344. public function getActual(): mixed
  99345. {
  99346. return $this->actual;
  99347. }
  99348. public function getExpected(): mixed
  99349. {
  99350. return $this->expected;
  99351. }
  99352. public function getActualAsString(): string
  99353. {
  99354. return $this->actualAsString;
  99355. }
  99356. public function getExpectedAsString(): string
  99357. {
  99358. return $this->expectedAsString;
  99359. }
  99360. public function getDiff(): string
  99361. {
  99362. if (!$this->actualAsString && !$this->expectedAsString) {
  99363. return '';
  99364. }
  99365. $differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n"));
  99366. return $differ->diff($this->expectedAsString, $this->actualAsString);
  99367. }
  99368. public function toString(): string
  99369. {
  99370. return $this->getMessage() . $this->getDiff();
  99371. }
  99372. }
  99373. <?php
  99374. declare (strict_types=1);
  99375. /*
  99376. * This file is part of sebastian/comparator.
  99377. *
  99378. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99379. *
  99380. * For the full copyright and license information, please view the LICENSE
  99381. * file that was distributed with this source code.
  99382. */
  99383. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99384. use function assert;
  99385. use function mb_strtolower;
  99386. use function sprintf;
  99387. use DOMDocument;
  99388. use DOMNode;
  99389. use ValueError;
  99390. final class DOMNodeComparator extends ObjectComparator
  99391. {
  99392. public function accepts(mixed $expected, mixed $actual): bool
  99393. {
  99394. return $expected instanceof DOMNode && $actual instanceof DOMNode;
  99395. }
  99396. /**
  99397. * @throws ComparisonFailure
  99398. */
  99399. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
  99400. {
  99401. assert($expected instanceof DOMNode);
  99402. assert($actual instanceof DOMNode);
  99403. $expectedAsString = $this->nodeToText($expected, \true, $ignoreCase);
  99404. $actualAsString = $this->nodeToText($actual, \true, $ignoreCase);
  99405. if ($expectedAsString !== $actualAsString) {
  99406. $type = $expected instanceof DOMDocument ? 'documents' : 'nodes';
  99407. throw new ComparisonFailure($expected, $actual, $expectedAsString, $actualAsString, sprintf("Failed asserting that two DOM %s are equal.\n", $type));
  99408. }
  99409. }
  99410. /**
  99411. * Returns the normalized, whitespace-cleaned, and indented textual
  99412. * representation of a DOMNode.
  99413. */
  99414. private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string
  99415. {
  99416. if ($canonicalize) {
  99417. $document = new DOMDocument();
  99418. try {
  99419. $c14n = $node->C14N();
  99420. assert(!empty($c14n));
  99421. @$document->loadXML($c14n);
  99422. } catch (ValueError) {
  99423. }
  99424. $node = $document;
  99425. }
  99426. $document = $node instanceof DOMDocument ? $node : $node->ownerDocument;
  99427. $document->formatOutput = \true;
  99428. $document->normalizeDocument();
  99429. $text = $node instanceof DOMDocument ? $node->saveXML() : $document->saveXML($node);
  99430. return $ignoreCase ? mb_strtolower($text, 'UTF-8') : $text;
  99431. }
  99432. }
  99433. <?php
  99434. declare (strict_types=1);
  99435. /*
  99436. * This file is part of sebastian/comparator.
  99437. *
  99438. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99439. *
  99440. * For the full copyright and license information, please view the LICENSE
  99441. * file that was distributed with this source code.
  99442. */
  99443. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99444. use function abs;
  99445. use function assert;
  99446. use function floor;
  99447. use function sprintf;
  99448. use DateInterval;
  99449. use DateTimeInterface;
  99450. use DateTimeZone;
  99451. final class DateTimeComparator extends ObjectComparator
  99452. {
  99453. public function accepts(mixed $expected, mixed $actual): bool
  99454. {
  99455. return $expected instanceof DateTimeInterface && $actual instanceof DateTimeInterface;
  99456. }
  99457. /**
  99458. * @throws ComparisonFailure
  99459. */
  99460. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
  99461. {
  99462. assert($expected instanceof DateTimeInterface);
  99463. assert($actual instanceof DateTimeInterface);
  99464. $absDelta = abs($delta);
  99465. $delta = new DateInterval(sprintf('PT%dS', $absDelta));
  99466. $delta->f = $absDelta - floor($absDelta);
  99467. $actualClone = (clone $actual)->setTimezone(new DateTimeZone('UTC'));
  99468. $expectedLower = (clone $expected)->setTimezone(new DateTimeZone('UTC'))->sub($delta);
  99469. $expectedUpper = (clone $expected)->setTimezone(new DateTimeZone('UTC'))->add($delta);
  99470. if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
  99471. throw new ComparisonFailure($expected, $actual, $this->dateTimeToString($expected), $this->dateTimeToString($actual), 'Failed asserting that two DateTime objects are equal.');
  99472. }
  99473. }
  99474. /**
  99475. * Returns an ISO 8601 formatted string representation of a datetime or
  99476. * 'Invalid DateTimeInterface object' if the provided DateTimeInterface was not properly
  99477. * initialized.
  99478. */
  99479. private function dateTimeToString(DateTimeInterface $datetime): string
  99480. {
  99481. $string = $datetime->format('Y-m-d\TH:i:s.uO');
  99482. return $string ?: 'Invalid DateTimeInterface object';
  99483. }
  99484. }
  99485. <?php
  99486. declare (strict_types=1);
  99487. /*
  99488. * This file is part of sebastian/comparator.
  99489. *
  99490. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99491. *
  99492. * For the full copyright and license information, please view the LICENSE
  99493. * file that was distributed with this source code.
  99494. */
  99495. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99496. use function assert;
  99497. use Exception;
  99498. /**
  99499. * Compares Exception instances for equality.
  99500. */
  99501. final class ExceptionComparator extends ObjectComparator
  99502. {
  99503. public function accepts(mixed $expected, mixed $actual): bool
  99504. {
  99505. return $expected instanceof Exception && $actual instanceof Exception;
  99506. }
  99507. protected function toArray(object $object): array
  99508. {
  99509. assert($object instanceof Exception);
  99510. $array = parent::toArray($object);
  99511. unset($array['file'], $array['line'], $array['trace'], $array['string'], $array['xdebug_message']);
  99512. return $array;
  99513. }
  99514. }
  99515. <?php
  99516. declare (strict_types=1);
  99517. /*
  99518. * This file is part of sebastian/comparator.
  99519. *
  99520. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99521. *
  99522. * For the full copyright and license information, please view the LICENSE
  99523. * file that was distributed with this source code.
  99524. */
  99525. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99526. use function array_unshift;
  99527. final class Factory
  99528. {
  99529. private static ?Factory $instance = null;
  99530. /**
  99531. * @psalm-var list<Comparator>
  99532. */
  99533. private array $customComparators = [];
  99534. /**
  99535. * @psalm-var list<Comparator>
  99536. */
  99537. private array $defaultComparators = [];
  99538. public static function getInstance(): self
  99539. {
  99540. if (self::$instance === null) {
  99541. self::$instance = new self();
  99542. // @codeCoverageIgnore
  99543. }
  99544. return self::$instance;
  99545. }
  99546. public function __construct()
  99547. {
  99548. $this->registerDefaultComparators();
  99549. }
  99550. public function getComparatorFor(mixed $expected, mixed $actual): Comparator
  99551. {
  99552. foreach ($this->customComparators as $comparator) {
  99553. if ($comparator->accepts($expected, $actual)) {
  99554. return $comparator;
  99555. }
  99556. }
  99557. foreach ($this->defaultComparators as $comparator) {
  99558. if ($comparator->accepts($expected, $actual)) {
  99559. return $comparator;
  99560. }
  99561. }
  99562. throw new RuntimeException('No suitable Comparator implementation found');
  99563. }
  99564. /**
  99565. * Registers a new comparator.
  99566. *
  99567. * This comparator will be returned by getComparatorFor() if its accept() method
  99568. * returns TRUE for the compared values. It has higher priority than the
  99569. * existing comparators, meaning that its accept() method will be invoked
  99570. * before those of the other comparators.
  99571. */
  99572. public function register(Comparator $comparator): void
  99573. {
  99574. array_unshift($this->customComparators, $comparator);
  99575. $comparator->setFactory($this);
  99576. }
  99577. /**
  99578. * Unregisters a comparator.
  99579. *
  99580. * This comparator will no longer be considered by getComparatorFor().
  99581. */
  99582. public function unregister(Comparator $comparator): void
  99583. {
  99584. foreach ($this->customComparators as $key => $_comparator) {
  99585. if ($comparator === $_comparator) {
  99586. unset($this->customComparators[$key]);
  99587. }
  99588. }
  99589. }
  99590. public function reset(): void
  99591. {
  99592. $this->customComparators = [];
  99593. }
  99594. private function registerDefaultComparators(): void
  99595. {
  99596. $this->registerDefaultComparator(new MockObjectComparator());
  99597. $this->registerDefaultComparator(new DateTimeComparator());
  99598. $this->registerDefaultComparator(new DOMNodeComparator());
  99599. $this->registerDefaultComparator(new SplObjectStorageComparator());
  99600. $this->registerDefaultComparator(new ExceptionComparator());
  99601. $this->registerDefaultComparator(new ObjectComparator());
  99602. $this->registerDefaultComparator(new ResourceComparator());
  99603. $this->registerDefaultComparator(new ArrayComparator());
  99604. $this->registerDefaultComparator(new NumericComparator());
  99605. $this->registerDefaultComparator(new ScalarComparator());
  99606. $this->registerDefaultComparator(new TypeComparator());
  99607. }
  99608. private function registerDefaultComparator(Comparator $comparator): void
  99609. {
  99610. $this->defaultComparators[] = $comparator;
  99611. $comparator->setFactory($this);
  99612. }
  99613. }
  99614. BSD 3-Clause License
  99615. Copyright (c) 2002-2024, Sebastian Bergmann
  99616. All rights reserved.
  99617. Redistribution and use in source and binary forms, with or without
  99618. modification, are permitted provided that the following conditions are met:
  99619. 1. Redistributions of source code must retain the above copyright notice, this
  99620. list of conditions and the following disclaimer.
  99621. 2. Redistributions in binary form must reproduce the above copyright notice,
  99622. this list of conditions and the following disclaimer in the documentation
  99623. and/or other materials provided with the distribution.
  99624. 3. Neither the name of the copyright holder nor the names of its
  99625. contributors may be used to endorse or promote products derived from
  99626. this software without specific prior written permission.
  99627. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  99628. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  99629. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  99630. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  99631. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  99632. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  99633. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  99634. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  99635. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  99636. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  99637. <?php
  99638. declare (strict_types=1);
  99639. /*
  99640. * This file is part of sebastian/comparator.
  99641. *
  99642. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99643. *
  99644. * For the full copyright and license information, please view the LICENSE
  99645. * file that was distributed with this source code.
  99646. */
  99647. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99648. use function array_keys;
  99649. use function assert;
  99650. use function str_starts_with;
  99651. use PHPUnit\Framework\MockObject\Stub;
  99652. /**
  99653. * Compares PHPUnit\Framework\MockObject\MockObject instances for equality.
  99654. */
  99655. final class MockObjectComparator extends ObjectComparator
  99656. {
  99657. public function accepts(mixed $expected, mixed $actual): bool
  99658. {
  99659. return $expected instanceof Stub && $actual instanceof Stub;
  99660. }
  99661. protected function toArray(object $object): array
  99662. {
  99663. assert($object instanceof Stub);
  99664. $array = parent::toArray($object);
  99665. foreach (array_keys($array) as $key) {
  99666. if (!str_starts_with($key, '__phpunit_')) {
  99667. continue;
  99668. }
  99669. unset($array[$key]);
  99670. }
  99671. return $array;
  99672. }
  99673. }
  99674. <?php
  99675. declare (strict_types=1);
  99676. /*
  99677. * This file is part of sebastian/comparator.
  99678. *
  99679. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99680. *
  99681. * For the full copyright and license information, please view the LICENSE
  99682. * file that was distributed with this source code.
  99683. */
  99684. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99685. use function abs;
  99686. use function is_float;
  99687. use function is_infinite;
  99688. use function is_nan;
  99689. use function is_numeric;
  99690. use function is_string;
  99691. use function sprintf;
  99692. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99693. final class NumericComparator extends ScalarComparator
  99694. {
  99695. public function accepts(mixed $expected, mixed $actual): bool
  99696. {
  99697. // all numerical values, but not if both of them are strings
  99698. return is_numeric($expected) && is_numeric($actual) && !(is_string($expected) && is_string($actual));
  99699. }
  99700. /**
  99701. * @throws ComparisonFailure
  99702. */
  99703. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
  99704. {
  99705. if ($this->isInfinite($actual) && $this->isInfinite($expected)) {
  99706. return;
  99707. }
  99708. if (($this->isInfinite($actual) xor $this->isInfinite($expected)) || ($this->isNan($actual) || $this->isNan($expected)) || abs($actual - $expected) > $delta) {
  99709. $exporter = new Exporter();
  99710. throw new ComparisonFailure($expected, $actual, '', '', sprintf('Failed asserting that %s matches expected %s.', $exporter->export($actual), $exporter->export($expected)));
  99711. }
  99712. }
  99713. private function isInfinite(mixed $value): bool
  99714. {
  99715. return is_float($value) && is_infinite($value);
  99716. }
  99717. private function isNan(mixed $value): bool
  99718. {
  99719. return is_float($value) && is_nan($value);
  99720. }
  99721. }
  99722. <?php
  99723. declare (strict_types=1);
  99724. /*
  99725. * This file is part of sebastian/comparator.
  99726. *
  99727. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99728. *
  99729. * For the full copyright and license information, please view the LICENSE
  99730. * file that was distributed with this source code.
  99731. */
  99732. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99733. use function assert;
  99734. use function in_array;
  99735. use function is_object;
  99736. use function sprintf;
  99737. use function substr_replace;
  99738. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99739. class ObjectComparator extends ArrayComparator
  99740. {
  99741. public function accepts(mixed $expected, mixed $actual): bool
  99742. {
  99743. return is_object($expected) && is_object($actual);
  99744. }
  99745. /**
  99746. * @throws ComparisonFailure
  99747. */
  99748. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
  99749. {
  99750. assert(is_object($expected));
  99751. assert(is_object($actual));
  99752. if ($actual::class !== $expected::class) {
  99753. $exporter = new Exporter();
  99754. throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), sprintf('%s is not instance of expected class "%s".', $exporter->export($actual), $expected::class));
  99755. }
  99756. // don't compare twice to allow for cyclic dependencies
  99757. if (in_array([$actual, $expected], $processed, \true) || in_array([$expected, $actual], $processed, \true)) {
  99758. return;
  99759. }
  99760. $processed[] = [$actual, $expected];
  99761. // don't compare objects if they are identical
  99762. // this helps to avoid the error "maximum function nesting level reached"
  99763. // CAUTION: this conditional clause is not tested
  99764. if ($actual !== $expected) {
  99765. try {
  99766. parent::assertEquals($this->toArray($expected), $this->toArray($actual), $delta, $canonicalize, $ignoreCase, $processed);
  99767. } catch (ComparisonFailure $e) {
  99768. throw new ComparisonFailure(
  99769. $expected,
  99770. $actual,
  99771. // replace "Array" with "MyClass object"
  99772. substr_replace($e->getExpectedAsString(), $expected::class . ' Object', 0, 5),
  99773. substr_replace($e->getActualAsString(), $actual::class . ' Object', 0, 5),
  99774. 'Failed asserting that two objects are equal.'
  99775. );
  99776. }
  99777. }
  99778. }
  99779. protected function toArray(object $object): array
  99780. {
  99781. return (new Exporter())->toArray($object);
  99782. }
  99783. }
  99784. <?php
  99785. declare (strict_types=1);
  99786. /*
  99787. * This file is part of sebastian/comparator.
  99788. *
  99789. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99790. *
  99791. * For the full copyright and license information, please view the LICENSE
  99792. * file that was distributed with this source code.
  99793. */
  99794. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99795. use function assert;
  99796. use function is_resource;
  99797. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99798. final class ResourceComparator extends Comparator
  99799. {
  99800. public function accepts(mixed $expected, mixed $actual): bool
  99801. {
  99802. return is_resource($expected) && is_resource($actual);
  99803. }
  99804. /**
  99805. * @throws ComparisonFailure
  99806. */
  99807. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
  99808. {
  99809. assert(is_resource($expected));
  99810. assert(is_resource($actual));
  99811. $exporter = new Exporter();
  99812. if ($actual != $expected) {
  99813. throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual));
  99814. }
  99815. }
  99816. }
  99817. <?php
  99818. declare (strict_types=1);
  99819. /*
  99820. * This file is part of sebastian/comparator.
  99821. *
  99822. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99823. *
  99824. * For the full copyright and license information, please view the LICENSE
  99825. * file that was distributed with this source code.
  99826. */
  99827. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99828. use function is_bool;
  99829. use function is_object;
  99830. use function is_scalar;
  99831. use function is_string;
  99832. use function mb_strtolower;
  99833. use function method_exists;
  99834. use function sprintf;
  99835. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99836. /**
  99837. * Compares scalar or NULL values for equality.
  99838. */
  99839. class ScalarComparator extends Comparator
  99840. {
  99841. public function accepts(mixed $expected, mixed $actual): bool
  99842. {
  99843. return (is_scalar($expected) xor null === $expected) && (is_scalar($actual) xor null === $actual) || is_string($expected) && is_object($actual) && method_exists($actual, '__toString') || is_object($expected) && method_exists($expected, '__toString') && is_string($actual);
  99844. }
  99845. /**
  99846. * @throws ComparisonFailure
  99847. */
  99848. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
  99849. {
  99850. $expectedToCompare = $expected;
  99851. $actualToCompare = $actual;
  99852. $exporter = new Exporter();
  99853. // always compare as strings to avoid strange behaviour
  99854. // otherwise 0 == 'Foobar'
  99855. if (is_string($expected) && !is_bool($actual) || is_string($actual) && !is_bool($expected)) {
  99856. $expectedToCompare = (string) $expectedToCompare;
  99857. $actualToCompare = (string) $actualToCompare;
  99858. if ($ignoreCase) {
  99859. $expectedToCompare = mb_strtolower($expectedToCompare, 'UTF-8');
  99860. $actualToCompare = mb_strtolower($actualToCompare, 'UTF-8');
  99861. }
  99862. }
  99863. if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) {
  99864. throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two strings are equal.');
  99865. }
  99866. if ($expectedToCompare != $actualToCompare) {
  99867. throw new ComparisonFailure(
  99868. $expected,
  99869. $actual,
  99870. // no diff is required
  99871. '',
  99872. '',
  99873. sprintf('Failed asserting that %s matches expected %s.', $exporter->export($actual), $exporter->export($expected))
  99874. );
  99875. }
  99876. }
  99877. }
  99878. <?php
  99879. declare (strict_types=1);
  99880. /*
  99881. * This file is part of sebastian/comparator.
  99882. *
  99883. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99884. *
  99885. * For the full copyright and license information, please view the LICENSE
  99886. * file that was distributed with this source code.
  99887. */
  99888. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99889. use function assert;
  99890. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99891. use SplObjectStorage;
  99892. final class SplObjectStorageComparator extends Comparator
  99893. {
  99894. public function accepts(mixed $expected, mixed $actual): bool
  99895. {
  99896. return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
  99897. }
  99898. /**
  99899. * @throws ComparisonFailure
  99900. */
  99901. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
  99902. {
  99903. assert($expected instanceof SplObjectStorage);
  99904. assert($actual instanceof SplObjectStorage);
  99905. $exporter = new Exporter();
  99906. foreach ($actual as $object) {
  99907. if (!$expected->contains($object)) {
  99908. throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two objects are equal.');
  99909. }
  99910. }
  99911. foreach ($expected as $object) {
  99912. if (!$actual->contains($object)) {
  99913. throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two objects are equal.');
  99914. }
  99915. }
  99916. }
  99917. }
  99918. <?php
  99919. declare (strict_types=1);
  99920. /*
  99921. * This file is part of sebastian/comparator.
  99922. *
  99923. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99924. *
  99925. * For the full copyright and license information, please view the LICENSE
  99926. * file that was distributed with this source code.
  99927. */
  99928. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99929. use function gettype;
  99930. use function sprintf;
  99931. use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
  99932. final class TypeComparator extends Comparator
  99933. {
  99934. public function accepts(mixed $expected, mixed $actual): bool
  99935. {
  99936. return \true;
  99937. }
  99938. /**
  99939. * @throws ComparisonFailure
  99940. */
  99941. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
  99942. {
  99943. if (gettype($expected) != gettype($actual)) {
  99944. throw new ComparisonFailure(
  99945. $expected,
  99946. $actual,
  99947. // we don't need a diff
  99948. '',
  99949. '',
  99950. sprintf('%s does not match expected type "%s".', (new Exporter())->shortenedExport($actual), gettype($expected))
  99951. );
  99952. }
  99953. }
  99954. }
  99955. <?php
  99956. declare (strict_types=1);
  99957. /*
  99958. * This file is part of sebastian/comparator.
  99959. *
  99960. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99961. *
  99962. * For the full copyright and license information, please view the LICENSE
  99963. * file that was distributed with this source code.
  99964. */
  99965. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99966. use Throwable;
  99967. interface Exception extends Throwable
  99968. {
  99969. }
  99970. <?php
  99971. declare (strict_types=1);
  99972. /*
  99973. * This file is part of sebastian/comparator.
  99974. *
  99975. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99976. *
  99977. * For the full copyright and license information, please view the LICENSE
  99978. * file that was distributed with this source code.
  99979. */
  99980. namespace PHPUnitPHAR\SebastianBergmann\Comparator;
  99981. final class RuntimeException extends \RuntimeException implements Exception
  99982. {
  99983. }
  99984. <?php
  99985. declare (strict_types=1);
  99986. /*
  99987. * This file is part of sebastian/complexity.
  99988. *
  99989. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  99990. *
  99991. * For the full copyright and license information, please view the LICENSE
  99992. * file that was distributed with this source code.
  99993. */
  99994. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  99995. use function assert;
  99996. use function file_get_contents;
  99997. use PHPUnitPHAR\PhpParser\Error;
  99998. use PHPUnitPHAR\PhpParser\Node;
  99999. use PHPUnitPHAR\PhpParser\NodeTraverser;
  100000. use PHPUnitPHAR\PhpParser\NodeVisitor\NameResolver;
  100001. use PHPUnitPHAR\PhpParser\NodeVisitor\ParentConnectingVisitor;
  100002. use PHPUnitPHAR\PhpParser\ParserFactory;
  100003. final class Calculator
  100004. {
  100005. /**
  100006. * @throws RuntimeException
  100007. */
  100008. public function calculateForSourceFile(string $sourceFile): ComplexityCollection
  100009. {
  100010. return $this->calculateForSourceString(file_get_contents($sourceFile));
  100011. }
  100012. /**
  100013. * @throws RuntimeException
  100014. */
  100015. public function calculateForSourceString(string $source): ComplexityCollection
  100016. {
  100017. try {
  100018. $nodes = (new ParserFactory())->createForHostVersion()->parse($source);
  100019. assert($nodes !== null);
  100020. return $this->calculateForAbstractSyntaxTree($nodes);
  100021. // @codeCoverageIgnoreStart
  100022. } catch (Error $error) {
  100023. throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
  100024. }
  100025. // @codeCoverageIgnoreEnd
  100026. }
  100027. /**
  100028. * @param Node[] $nodes
  100029. *
  100030. * @throws RuntimeException
  100031. */
  100032. public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection
  100033. {
  100034. $traverser = new NodeTraverser();
  100035. $complexityCalculatingVisitor = new ComplexityCalculatingVisitor(\true);
  100036. $traverser->addVisitor(new NameResolver());
  100037. $traverser->addVisitor(new ParentConnectingVisitor());
  100038. $traverser->addVisitor($complexityCalculatingVisitor);
  100039. try {
  100040. /* @noinspection UnusedFunctionResultInspection */
  100041. $traverser->traverse($nodes);
  100042. // @codeCoverageIgnoreStart
  100043. } catch (Error $error) {
  100044. throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
  100045. }
  100046. // @codeCoverageIgnoreEnd
  100047. return $complexityCalculatingVisitor->result();
  100048. }
  100049. }
  100050. <?php
  100051. declare (strict_types=1);
  100052. /*
  100053. * This file is part of sebastian/complexity.
  100054. *
  100055. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100056. *
  100057. * For the full copyright and license information, please view the LICENSE
  100058. * file that was distributed with this source code.
  100059. */
  100060. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100061. use function str_contains;
  100062. /**
  100063. * @psalm-immutable
  100064. */
  100065. final class Complexity
  100066. {
  100067. /**
  100068. * @psalm-var non-empty-string
  100069. */
  100070. private readonly string $name;
  100071. /**
  100072. * @psalm-var positive-int
  100073. */
  100074. private int $cyclomaticComplexity;
  100075. /**
  100076. * @psalm-param non-empty-string $name
  100077. * @psalm-param positive-int $cyclomaticComplexity
  100078. */
  100079. public function __construct(string $name, int $cyclomaticComplexity)
  100080. {
  100081. $this->name = $name;
  100082. $this->cyclomaticComplexity = $cyclomaticComplexity;
  100083. }
  100084. /**
  100085. * @psalm-return non-empty-string
  100086. */
  100087. public function name(): string
  100088. {
  100089. return $this->name;
  100090. }
  100091. /**
  100092. * @psalm-return positive-int
  100093. */
  100094. public function cyclomaticComplexity(): int
  100095. {
  100096. return $this->cyclomaticComplexity;
  100097. }
  100098. public function isFunction(): bool
  100099. {
  100100. return !$this->isMethod();
  100101. }
  100102. public function isMethod(): bool
  100103. {
  100104. return str_contains($this->name, '::');
  100105. }
  100106. }
  100107. <?php
  100108. declare (strict_types=1);
  100109. /*
  100110. * This file is part of sebastian/complexity.
  100111. *
  100112. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100113. *
  100114. * For the full copyright and license information, please view the LICENSE
  100115. * file that was distributed with this source code.
  100116. */
  100117. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100118. use function array_filter;
  100119. use function array_merge;
  100120. use function array_reverse;
  100121. use function array_values;
  100122. use function count;
  100123. use function usort;
  100124. use Countable;
  100125. use IteratorAggregate;
  100126. /**
  100127. * @psalm-immutable
  100128. */
  100129. final class ComplexityCollection implements Countable, IteratorAggregate
  100130. {
  100131. /**
  100132. * @psalm-var list<Complexity>
  100133. */
  100134. private readonly array $items;
  100135. public static function fromList(Complexity ...$items): self
  100136. {
  100137. return new self($items);
  100138. }
  100139. /**
  100140. * @psalm-param list<Complexity> $items
  100141. */
  100142. private function __construct(array $items)
  100143. {
  100144. $this->items = $items;
  100145. }
  100146. /**
  100147. * @psalm-return list<Complexity>
  100148. */
  100149. public function asArray(): array
  100150. {
  100151. return $this->items;
  100152. }
  100153. public function getIterator(): ComplexityCollectionIterator
  100154. {
  100155. return new ComplexityCollectionIterator($this);
  100156. }
  100157. /**
  100158. * @psalm-return non-negative-int
  100159. */
  100160. public function count(): int
  100161. {
  100162. return count($this->items);
  100163. }
  100164. public function isEmpty(): bool
  100165. {
  100166. return empty($this->items);
  100167. }
  100168. /**
  100169. * @psalm-return non-negative-int
  100170. */
  100171. public function cyclomaticComplexity(): int
  100172. {
  100173. $cyclomaticComplexity = 0;
  100174. foreach ($this as $item) {
  100175. $cyclomaticComplexity += $item->cyclomaticComplexity();
  100176. }
  100177. return $cyclomaticComplexity;
  100178. }
  100179. public function isFunction(): self
  100180. {
  100181. return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isFunction())));
  100182. }
  100183. public function isMethod(): self
  100184. {
  100185. return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isMethod())));
  100186. }
  100187. public function mergeWith(self $other): self
  100188. {
  100189. return new self(array_merge($this->asArray(), $other->asArray()));
  100190. }
  100191. public function sortByDescendingCyclomaticComplexity(): self
  100192. {
  100193. $items = $this->items;
  100194. usort($items, static function (Complexity $a, Complexity $b): int {
  100195. return $a->cyclomaticComplexity() <=> $b->cyclomaticComplexity();
  100196. });
  100197. return new self(array_reverse($items));
  100198. }
  100199. }
  100200. <?php
  100201. declare (strict_types=1);
  100202. /*
  100203. * This file is part of sebastian/complexity.
  100204. *
  100205. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100206. *
  100207. * For the full copyright and license information, please view the LICENSE
  100208. * file that was distributed with this source code.
  100209. */
  100210. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100211. use Iterator;
  100212. final class ComplexityCollectionIterator implements Iterator
  100213. {
  100214. /**
  100215. * @psalm-var list<Complexity>
  100216. */
  100217. private readonly array $items;
  100218. private int $position = 0;
  100219. public function __construct(ComplexityCollection $items)
  100220. {
  100221. $this->items = $items->asArray();
  100222. }
  100223. public function rewind(): void
  100224. {
  100225. $this->position = 0;
  100226. }
  100227. public function valid(): bool
  100228. {
  100229. return isset($this->items[$this->position]);
  100230. }
  100231. public function key(): int
  100232. {
  100233. return $this->position;
  100234. }
  100235. public function current(): Complexity
  100236. {
  100237. return $this->items[$this->position];
  100238. }
  100239. public function next(): void
  100240. {
  100241. $this->position++;
  100242. }
  100243. }
  100244. <?php
  100245. declare (strict_types=1);
  100246. /*
  100247. * This file is part of sebastian/complexity.
  100248. *
  100249. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100250. *
  100251. * For the full copyright and license information, please view the LICENSE
  100252. * file that was distributed with this source code.
  100253. */
  100254. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100255. use Throwable;
  100256. interface Exception extends Throwable
  100257. {
  100258. }
  100259. <?php
  100260. declare (strict_types=1);
  100261. /*
  100262. * This file is part of sebastian/complexity.
  100263. *
  100264. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100265. *
  100266. * For the full copyright and license information, please view the LICENSE
  100267. * file that was distributed with this source code.
  100268. */
  100269. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100270. final class RuntimeException extends \RuntimeException implements Exception
  100271. {
  100272. }
  100273. BSD 3-Clause License
  100274. Copyright (c) 2020-2023, Sebastian Bergmann
  100275. All rights reserved.
  100276. Redistribution and use in source and binary forms, with or without
  100277. modification, are permitted provided that the following conditions are met:
  100278. 1. Redistributions of source code must retain the above copyright notice, this
  100279. list of conditions and the following disclaimer.
  100280. 2. Redistributions in binary form must reproduce the above copyright notice,
  100281. this list of conditions and the following disclaimer in the documentation
  100282. and/or other materials provided with the distribution.
  100283. 3. Neither the name of the copyright holder nor the names of its
  100284. contributors may be used to endorse or promote products derived from
  100285. this software without specific prior written permission.
  100286. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  100287. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  100288. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  100289. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  100290. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  100291. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  100292. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  100293. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  100294. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  100295. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  100296. <?php
  100297. declare (strict_types=1);
  100298. /*
  100299. * This file is part of sebastian/complexity.
  100300. *
  100301. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100302. *
  100303. * For the full copyright and license information, please view the LICENSE
  100304. * file that was distributed with this source code.
  100305. */
  100306. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100307. use function assert;
  100308. use function is_array;
  100309. use PHPUnitPHAR\PhpParser\Node;
  100310. use PHPUnitPHAR\PhpParser\Node\Expr\New_;
  100311. use PHPUnitPHAR\PhpParser\Node\Name;
  100312. use PHPUnitPHAR\PhpParser\Node\Stmt;
  100313. use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
  100314. use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
  100315. use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
  100316. use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
  100317. use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
  100318. use PHPUnitPHAR\PhpParser\NodeTraverser;
  100319. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  100320. final class ComplexityCalculatingVisitor extends NodeVisitorAbstract
  100321. {
  100322. /**
  100323. * @psalm-var list<Complexity>
  100324. */
  100325. private array $result = [];
  100326. private bool $shortCircuitTraversal;
  100327. public function __construct(bool $shortCircuitTraversal)
  100328. {
  100329. $this->shortCircuitTraversal = $shortCircuitTraversal;
  100330. }
  100331. public function enterNode(Node $node): ?int
  100332. {
  100333. if (!$node instanceof ClassMethod && !$node instanceof Function_) {
  100334. return null;
  100335. }
  100336. if ($node instanceof ClassMethod) {
  100337. if ($node->getAttribute('parent') instanceof Interface_) {
  100338. return null;
  100339. }
  100340. if ($node->isAbstract()) {
  100341. return null;
  100342. }
  100343. $name = $this->classMethodName($node);
  100344. } else {
  100345. $name = $this->functionName($node);
  100346. }
  100347. $statements = $node->getStmts();
  100348. assert(is_array($statements));
  100349. $this->result[] = new Complexity($name, $this->cyclomaticComplexity($statements));
  100350. if ($this->shortCircuitTraversal) {
  100351. return NodeTraverser::DONT_TRAVERSE_CHILDREN;
  100352. }
  100353. return null;
  100354. }
  100355. public function result(): ComplexityCollection
  100356. {
  100357. return ComplexityCollection::fromList(...$this->result);
  100358. }
  100359. /**
  100360. * @param Stmt[] $statements
  100361. *
  100362. * @psalm-return positive-int
  100363. */
  100364. private function cyclomaticComplexity(array $statements): int
  100365. {
  100366. $traverser = new NodeTraverser();
  100367. $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor();
  100368. $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
  100369. /* @noinspection UnusedFunctionResultInspection */
  100370. $traverser->traverse($statements);
  100371. return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
  100372. }
  100373. /**
  100374. * @psalm-return non-empty-string
  100375. */
  100376. private function classMethodName(ClassMethod $node): string
  100377. {
  100378. $parent = $node->getAttribute('parent');
  100379. assert($parent instanceof Class_ || $parent instanceof Trait_);
  100380. if ($parent->getAttribute('parent') instanceof New_) {
  100381. return 'anonymous class';
  100382. }
  100383. assert(isset($parent->namespacedName));
  100384. assert($parent->namespacedName instanceof Name);
  100385. return $parent->namespacedName->toString() . '::' . $node->name->toString();
  100386. }
  100387. /**
  100388. * @psalm-return non-empty-string
  100389. */
  100390. private function functionName(Function_ $node): string
  100391. {
  100392. assert(isset($node->namespacedName));
  100393. assert($node->namespacedName instanceof Name);
  100394. $functionName = $node->namespacedName->toString();
  100395. assert($functionName !== '');
  100396. return $functionName;
  100397. }
  100398. }
  100399. <?php
  100400. declare (strict_types=1);
  100401. /*
  100402. * This file is part of sebastian/complexity.
  100403. *
  100404. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100405. *
  100406. * For the full copyright and license information, please view the LICENSE
  100407. * file that was distributed with this source code.
  100408. */
  100409. namespace PHPUnitPHAR\SebastianBergmann\Complexity;
  100410. use PHPUnitPHAR\PhpParser\Node;
  100411. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\BooleanAnd;
  100412. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\BooleanOr;
  100413. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\LogicalAnd;
  100414. use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\LogicalOr;
  100415. use PHPUnitPHAR\PhpParser\Node\Expr\Ternary;
  100416. use PHPUnitPHAR\PhpParser\Node\Stmt\Case_;
  100417. use PHPUnitPHAR\PhpParser\Node\Stmt\Catch_;
  100418. use PHPUnitPHAR\PhpParser\Node\Stmt\ElseIf_;
  100419. use PHPUnitPHAR\PhpParser\Node\Stmt\For_;
  100420. use PHPUnitPHAR\PhpParser\Node\Stmt\Foreach_;
  100421. use PHPUnitPHAR\PhpParser\Node\Stmt\If_;
  100422. use PHPUnitPHAR\PhpParser\Node\Stmt\While_;
  100423. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  100424. final class CyclomaticComplexityCalculatingVisitor extends NodeVisitorAbstract
  100425. {
  100426. /**
  100427. * @psalm-var positive-int
  100428. */
  100429. private int $cyclomaticComplexity = 1;
  100430. public function enterNode(Node $node): void
  100431. {
  100432. switch ($node::class) {
  100433. case BooleanAnd::class:
  100434. case BooleanOr::class:
  100435. case Case_::class:
  100436. case Catch_::class:
  100437. case ElseIf_::class:
  100438. case For_::class:
  100439. case Foreach_::class:
  100440. case If_::class:
  100441. case LogicalAnd::class:
  100442. case LogicalOr::class:
  100443. case Ternary::class:
  100444. case While_::class:
  100445. $this->cyclomaticComplexity++;
  100446. }
  100447. }
  100448. /**
  100449. * @psalm-return positive-int
  100450. */
  100451. public function cyclomaticComplexity(): int
  100452. {
  100453. return $this->cyclomaticComplexity;
  100454. }
  100455. }
  100456. <?php
  100457. declare (strict_types=1);
  100458. /*
  100459. * This file is part of sebastian/diff.
  100460. *
  100461. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100462. *
  100463. * For the full copyright and license information, please view the LICENSE
  100464. * file that was distributed with this source code.
  100465. */
  100466. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100467. use ArrayIterator;
  100468. use IteratorAggregate;
  100469. use Traversable;
  100470. /**
  100471. * @template-implements IteratorAggregate<int, Line>
  100472. */
  100473. final class Chunk implements IteratorAggregate
  100474. {
  100475. private int $start;
  100476. private int $startRange;
  100477. private int $end;
  100478. private int $endRange;
  100479. private array $lines;
  100480. public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = [])
  100481. {
  100482. $this->start = $start;
  100483. $this->startRange = $startRange;
  100484. $this->end = $end;
  100485. $this->endRange = $endRange;
  100486. $this->lines = $lines;
  100487. }
  100488. public function start(): int
  100489. {
  100490. return $this->start;
  100491. }
  100492. public function startRange(): int
  100493. {
  100494. return $this->startRange;
  100495. }
  100496. public function end(): int
  100497. {
  100498. return $this->end;
  100499. }
  100500. public function endRange(): int
  100501. {
  100502. return $this->endRange;
  100503. }
  100504. /**
  100505. * @psalm-return list<Line>
  100506. */
  100507. public function lines(): array
  100508. {
  100509. return $this->lines;
  100510. }
  100511. /**
  100512. * @psalm-param list<Line> $lines
  100513. */
  100514. public function setLines(array $lines): void
  100515. {
  100516. foreach ($lines as $line) {
  100517. if (!$line instanceof Line) {
  100518. throw new InvalidArgumentException();
  100519. }
  100520. }
  100521. $this->lines = $lines;
  100522. }
  100523. /**
  100524. * @deprecated Use start() instead
  100525. */
  100526. public function getStart(): int
  100527. {
  100528. return $this->start;
  100529. }
  100530. /**
  100531. * @deprecated Use startRange() instead
  100532. */
  100533. public function getStartRange(): int
  100534. {
  100535. return $this->startRange;
  100536. }
  100537. /**
  100538. * @deprecated Use end() instead
  100539. */
  100540. public function getEnd(): int
  100541. {
  100542. return $this->end;
  100543. }
  100544. /**
  100545. * @deprecated Use endRange() instead
  100546. */
  100547. public function getEndRange(): int
  100548. {
  100549. return $this->endRange;
  100550. }
  100551. /**
  100552. * @psalm-return list<Line>
  100553. *
  100554. * @deprecated Use lines() instead
  100555. */
  100556. public function getLines(): array
  100557. {
  100558. return $this->lines;
  100559. }
  100560. public function getIterator(): Traversable
  100561. {
  100562. return new ArrayIterator($this->lines);
  100563. }
  100564. }
  100565. <?php
  100566. declare (strict_types=1);
  100567. /*
  100568. * This file is part of sebastian/diff.
  100569. *
  100570. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100571. *
  100572. * For the full copyright and license information, please view the LICENSE
  100573. * file that was distributed with this source code.
  100574. */
  100575. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100576. use ArrayIterator;
  100577. use IteratorAggregate;
  100578. use Traversable;
  100579. /**
  100580. * @template-implements IteratorAggregate<int, Chunk>
  100581. */
  100582. final class Diff implements IteratorAggregate
  100583. {
  100584. /**
  100585. * @psalm-var non-empty-string
  100586. */
  100587. private string $from;
  100588. /**
  100589. * @psalm-var non-empty-string
  100590. */
  100591. private string $to;
  100592. /**
  100593. * @psalm-var list<Chunk>
  100594. */
  100595. private array $chunks;
  100596. /**
  100597. * @psalm-param non-empty-string $from
  100598. * @psalm-param non-empty-string $to
  100599. * @psalm-param list<Chunk> $chunks
  100600. */
  100601. public function __construct(string $from, string $to, array $chunks = [])
  100602. {
  100603. $this->from = $from;
  100604. $this->to = $to;
  100605. $this->chunks = $chunks;
  100606. }
  100607. /**
  100608. * @psalm-return non-empty-string
  100609. */
  100610. public function from(): string
  100611. {
  100612. return $this->from;
  100613. }
  100614. /**
  100615. * @psalm-return non-empty-string
  100616. */
  100617. public function to(): string
  100618. {
  100619. return $this->to;
  100620. }
  100621. /**
  100622. * @psalm-return list<Chunk>
  100623. */
  100624. public function chunks(): array
  100625. {
  100626. return $this->chunks;
  100627. }
  100628. /**
  100629. * @psalm-param list<Chunk> $chunks
  100630. */
  100631. public function setChunks(array $chunks): void
  100632. {
  100633. $this->chunks = $chunks;
  100634. }
  100635. /**
  100636. * @psalm-return non-empty-string
  100637. *
  100638. * @deprecated
  100639. */
  100640. public function getFrom(): string
  100641. {
  100642. return $this->from;
  100643. }
  100644. /**
  100645. * @psalm-return non-empty-string
  100646. *
  100647. * @deprecated
  100648. */
  100649. public function getTo(): string
  100650. {
  100651. return $this->to;
  100652. }
  100653. /**
  100654. * @psalm-return list<Chunk>
  100655. *
  100656. * @deprecated
  100657. */
  100658. public function getChunks(): array
  100659. {
  100660. return $this->chunks;
  100661. }
  100662. public function getIterator(): Traversable
  100663. {
  100664. return new ArrayIterator($this->chunks);
  100665. }
  100666. }
  100667. <?php
  100668. declare (strict_types=1);
  100669. /*
  100670. * This file is part of sebastian/diff.
  100671. *
  100672. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100673. *
  100674. * For the full copyright and license information, please view the LICENSE
  100675. * file that was distributed with this source code.
  100676. */
  100677. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100678. use const PHP_INT_SIZE;
  100679. use const PREG_SPLIT_DELIM_CAPTURE;
  100680. use const PREG_SPLIT_NO_EMPTY;
  100681. use function array_shift;
  100682. use function array_unshift;
  100683. use function array_values;
  100684. use function count;
  100685. use function current;
  100686. use function end;
  100687. use function is_string;
  100688. use function key;
  100689. use function min;
  100690. use function preg_split;
  100691. use function prev;
  100692. use function reset;
  100693. use function str_ends_with;
  100694. use function substr;
  100695. use PHPUnitPHAR\SebastianBergmann\Diff\Output\DiffOutputBuilderInterface;
  100696. final class Differ
  100697. {
  100698. public const OLD = 0;
  100699. public const ADDED = 1;
  100700. public const REMOVED = 2;
  100701. public const DIFF_LINE_END_WARNING = 3;
  100702. public const NO_LINE_END_EOF_WARNING = 4;
  100703. private DiffOutputBuilderInterface $outputBuilder;
  100704. public function __construct(DiffOutputBuilderInterface $outputBuilder)
  100705. {
  100706. $this->outputBuilder = $outputBuilder;
  100707. }
  100708. public function diff(array|string $from, array|string $to, ?LongestCommonSubsequenceCalculator $lcs = null): string
  100709. {
  100710. $diff = $this->diffToArray($from, $to, $lcs);
  100711. return $this->outputBuilder->getDiff($diff);
  100712. }
  100713. public function diffToArray(array|string $from, array|string $to, ?LongestCommonSubsequenceCalculator $lcs = null): array
  100714. {
  100715. if (is_string($from)) {
  100716. $from = $this->splitStringByLines($from);
  100717. }
  100718. if (is_string($to)) {
  100719. $to = $this->splitStringByLines($to);
  100720. }
  100721. [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to);
  100722. if ($lcs === null) {
  100723. $lcs = $this->selectLcsImplementation($from, $to);
  100724. }
  100725. $common = $lcs->calculate(array_values($from), array_values($to));
  100726. $diff = [];
  100727. foreach ($start as $token) {
  100728. $diff[] = [$token, self::OLD];
  100729. }
  100730. reset($from);
  100731. reset($to);
  100732. foreach ($common as $token) {
  100733. while (($fromToken = reset($from)) !== $token) {
  100734. $diff[] = [array_shift($from), self::REMOVED];
  100735. }
  100736. while (($toToken = reset($to)) !== $token) {
  100737. $diff[] = [array_shift($to), self::ADDED];
  100738. }
  100739. $diff[] = [$token, self::OLD];
  100740. array_shift($from);
  100741. array_shift($to);
  100742. }
  100743. while (($token = array_shift($from)) !== null) {
  100744. $diff[] = [$token, self::REMOVED];
  100745. }
  100746. while (($token = array_shift($to)) !== null) {
  100747. $diff[] = [$token, self::ADDED];
  100748. }
  100749. foreach ($end as $token) {
  100750. $diff[] = [$token, self::OLD];
  100751. }
  100752. if ($this->detectUnmatchedLineEndings($diff)) {
  100753. array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]);
  100754. }
  100755. return $diff;
  100756. }
  100757. private function splitStringByLines(string $input): array
  100758. {
  100759. return preg_split('/(.*\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
  100760. }
  100761. private function selectLcsImplementation(array $from, array $to): LongestCommonSubsequenceCalculator
  100762. {
  100763. // We do not want to use the time-efficient implementation if its memory
  100764. // footprint will probably exceed this value. Note that the footprint
  100765. // calculation is only an estimation for the matrix and the LCS method
  100766. // will typically allocate a bit more memory than this.
  100767. $memoryLimit = 100 * 1024 * 1024;
  100768. if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
  100769. return new MemoryEfficientLongestCommonSubsequenceCalculator();
  100770. }
  100771. return new TimeEfficientLongestCommonSubsequenceCalculator();
  100772. }
  100773. private function calculateEstimatedFootprint(array $from, array $to): float|int
  100774. {
  100775. $itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
  100776. return $itemSize * min(count($from), count($to)) ** 2;
  100777. }
  100778. private function detectUnmatchedLineEndings(array $diff): bool
  100779. {
  100780. $newLineBreaks = ['' => \true];
  100781. $oldLineBreaks = ['' => \true];
  100782. foreach ($diff as $entry) {
  100783. if (self::OLD === $entry[1]) {
  100784. $ln = $this->getLinebreak($entry[0]);
  100785. $oldLineBreaks[$ln] = \true;
  100786. $newLineBreaks[$ln] = \true;
  100787. } elseif (self::ADDED === $entry[1]) {
  100788. $newLineBreaks[$this->getLinebreak($entry[0])] = \true;
  100789. } elseif (self::REMOVED === $entry[1]) {
  100790. $oldLineBreaks[$this->getLinebreak($entry[0])] = \true;
  100791. }
  100792. }
  100793. // if either input or output is a single line without breaks than no warning should be raised
  100794. if (['' => \true] === $newLineBreaks || ['' => \true] === $oldLineBreaks) {
  100795. return \false;
  100796. }
  100797. // two-way compare
  100798. foreach ($newLineBreaks as $break => $set) {
  100799. if (!isset($oldLineBreaks[$break])) {
  100800. return \true;
  100801. }
  100802. }
  100803. foreach ($oldLineBreaks as $break => $set) {
  100804. if (!isset($newLineBreaks[$break])) {
  100805. return \true;
  100806. }
  100807. }
  100808. return \false;
  100809. }
  100810. private function getLinebreak($line): string
  100811. {
  100812. if (!is_string($line)) {
  100813. return '';
  100814. }
  100815. $lc = substr($line, -1);
  100816. if ("\r" === $lc) {
  100817. return "\r";
  100818. }
  100819. if ("\n" !== $lc) {
  100820. return '';
  100821. }
  100822. if (str_ends_with($line, "\r\n")) {
  100823. return "\r\n";
  100824. }
  100825. return "\n";
  100826. }
  100827. private static function getArrayDiffParted(array &$from, array &$to): array
  100828. {
  100829. $start = [];
  100830. $end = [];
  100831. reset($to);
  100832. foreach ($from as $k => $v) {
  100833. $toK = key($to);
  100834. if ($toK === $k && $v === $to[$k]) {
  100835. $start[$k] = $v;
  100836. unset($from[$k], $to[$k]);
  100837. } else {
  100838. break;
  100839. }
  100840. }
  100841. end($from);
  100842. end($to);
  100843. do {
  100844. $fromK = key($from);
  100845. $toK = key($to);
  100846. if (null === $fromK || null === $toK || current($from) !== current($to)) {
  100847. break;
  100848. }
  100849. prev($from);
  100850. prev($to);
  100851. $end = [$fromK => $from[$fromK]] + $end;
  100852. unset($from[$fromK], $to[$toK]);
  100853. } while (\true);
  100854. return [$from, $to, $start, $end];
  100855. }
  100856. }
  100857. <?php
  100858. declare (strict_types=1);
  100859. /*
  100860. * This file is part of sebastian/diff.
  100861. *
  100862. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100863. *
  100864. * For the full copyright and license information, please view the LICENSE
  100865. * file that was distributed with this source code.
  100866. */
  100867. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100868. use function gettype;
  100869. use function is_object;
  100870. use function sprintf;
  100871. use Exception;
  100872. final class ConfigurationException extends InvalidArgumentException
  100873. {
  100874. public function __construct(string $option, string $expected, $value, int $code = 0, ?Exception $previous = null)
  100875. {
  100876. parent::__construct(sprintf('Option "%s" must be %s, got "%s".', $option, $expected, is_object($value) ? $value::class : (null === $value ? '<null>' : gettype($value) . '#' . $value)), $code, $previous);
  100877. }
  100878. }
  100879. <?php
  100880. declare (strict_types=1);
  100881. /*
  100882. * This file is part of sebastian/diff.
  100883. *
  100884. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100885. *
  100886. * For the full copyright and license information, please view the LICENSE
  100887. * file that was distributed with this source code.
  100888. */
  100889. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100890. use Throwable;
  100891. interface Exception extends Throwable
  100892. {
  100893. }
  100894. <?php
  100895. declare (strict_types=1);
  100896. /*
  100897. * This file is part of sebastian/diff.
  100898. *
  100899. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100900. *
  100901. * For the full copyright and license information, please view the LICENSE
  100902. * file that was distributed with this source code.
  100903. */
  100904. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100905. class InvalidArgumentException extends \InvalidArgumentException implements Exception
  100906. {
  100907. }
  100908. BSD 3-Clause License
  100909. Copyright (c) 2002-2024, Sebastian Bergmann
  100910. All rights reserved.
  100911. Redistribution and use in source and binary forms, with or without
  100912. modification, are permitted provided that the following conditions are met:
  100913. 1. Redistributions of source code must retain the above copyright notice, this
  100914. list of conditions and the following disclaimer.
  100915. 2. Redistributions in binary form must reproduce the above copyright notice,
  100916. this list of conditions and the following disclaimer in the documentation
  100917. and/or other materials provided with the distribution.
  100918. 3. Neither the name of the copyright holder nor the names of its
  100919. contributors may be used to endorse or promote products derived from
  100920. this software without specific prior written permission.
  100921. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  100922. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  100923. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  100924. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  100925. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  100926. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  100927. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  100928. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  100929. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  100930. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  100931. <?php
  100932. declare (strict_types=1);
  100933. /*
  100934. * This file is part of sebastian/diff.
  100935. *
  100936. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100937. *
  100938. * For the full copyright and license information, please view the LICENSE
  100939. * file that was distributed with this source code.
  100940. */
  100941. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  100942. final class Line
  100943. {
  100944. public const ADDED = 1;
  100945. public const REMOVED = 2;
  100946. public const UNCHANGED = 3;
  100947. private int $type;
  100948. private string $content;
  100949. public function __construct(int $type = self::UNCHANGED, string $content = '')
  100950. {
  100951. $this->type = $type;
  100952. $this->content = $content;
  100953. }
  100954. public function content(): string
  100955. {
  100956. return $this->content;
  100957. }
  100958. public function type(): int
  100959. {
  100960. return $this->type;
  100961. }
  100962. public function isAdded(): bool
  100963. {
  100964. return $this->type === self::ADDED;
  100965. }
  100966. public function isRemoved(): bool
  100967. {
  100968. return $this->type === self::REMOVED;
  100969. }
  100970. public function isUnchanged(): bool
  100971. {
  100972. return $this->type === self::UNCHANGED;
  100973. }
  100974. /**
  100975. * @deprecated
  100976. */
  100977. public function getContent(): string
  100978. {
  100979. return $this->content;
  100980. }
  100981. /**
  100982. * @deprecated
  100983. */
  100984. public function getType(): int
  100985. {
  100986. return $this->type;
  100987. }
  100988. }
  100989. <?php
  100990. declare (strict_types=1);
  100991. /*
  100992. * This file is part of sebastian/diff.
  100993. *
  100994. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  100995. *
  100996. * For the full copyright and license information, please view the LICENSE
  100997. * file that was distributed with this source code.
  100998. */
  100999. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  101000. interface LongestCommonSubsequenceCalculator
  101001. {
  101002. /**
  101003. * Calculates the longest common subsequence of two arrays.
  101004. */
  101005. public function calculate(array $from, array $to): array;
  101006. }
  101007. <?php
  101008. declare (strict_types=1);
  101009. /*
  101010. * This file is part of sebastian/diff.
  101011. *
  101012. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101013. *
  101014. * For the full copyright and license information, please view the LICENSE
  101015. * file that was distributed with this source code.
  101016. */
  101017. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  101018. use function array_fill;
  101019. use function array_merge;
  101020. use function array_reverse;
  101021. use function array_slice;
  101022. use function count;
  101023. use function in_array;
  101024. use function max;
  101025. final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
  101026. {
  101027. /**
  101028. * @inheritDoc
  101029. */
  101030. public function calculate(array $from, array $to): array
  101031. {
  101032. $cFrom = count($from);
  101033. $cTo = count($to);
  101034. if ($cFrom === 0) {
  101035. return [];
  101036. }
  101037. if ($cFrom === 1) {
  101038. if (in_array($from[0], $to, \true)) {
  101039. return [$from[0]];
  101040. }
  101041. return [];
  101042. }
  101043. $i = (int) ($cFrom / 2);
  101044. $fromStart = array_slice($from, 0, $i);
  101045. $fromEnd = array_slice($from, $i);
  101046. $llB = $this->length($fromStart, $to);
  101047. $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
  101048. $jMax = 0;
  101049. $max = 0;
  101050. for ($j = 0; $j <= $cTo; $j++) {
  101051. $m = $llB[$j] + $llE[$cTo - $j];
  101052. if ($m >= $max) {
  101053. $max = $m;
  101054. $jMax = $j;
  101055. }
  101056. }
  101057. $toStart = array_slice($to, 0, $jMax);
  101058. $toEnd = array_slice($to, $jMax);
  101059. return array_merge($this->calculate($fromStart, $toStart), $this->calculate($fromEnd, $toEnd));
  101060. }
  101061. private function length(array $from, array $to): array
  101062. {
  101063. $current = array_fill(0, count($to) + 1, 0);
  101064. $cFrom = count($from);
  101065. $cTo = count($to);
  101066. for ($i = 0; $i < $cFrom; $i++) {
  101067. $prev = $current;
  101068. for ($j = 0; $j < $cTo; $j++) {
  101069. if ($from[$i] === $to[$j]) {
  101070. $current[$j + 1] = $prev[$j] + 1;
  101071. } else if ($current[$j] > $prev[$j + 1]) {
  101072. $current[$j + 1] = $current[$j];
  101073. } else {
  101074. $current[$j + 1] = $prev[$j + 1];
  101075. }
  101076. }
  101077. }
  101078. return $current;
  101079. }
  101080. }
  101081. <?php
  101082. declare (strict_types=1);
  101083. /*
  101084. * This file is part of sebastian/diff.
  101085. *
  101086. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101087. *
  101088. * For the full copyright and license information, please view the LICENSE
  101089. * file that was distributed with this source code.
  101090. */
  101091. namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
  101092. use function count;
  101093. abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface
  101094. {
  101095. /**
  101096. * Takes input of the diff array and returns the common parts.
  101097. * Iterates through diff line by line.
  101098. */
  101099. protected function getCommonChunks(array $diff, int $lineThreshold = 5): array
  101100. {
  101101. $diffSize = count($diff);
  101102. $capturing = \false;
  101103. $chunkStart = 0;
  101104. $chunkSize = 0;
  101105. $commonChunks = [];
  101106. for ($i = 0; $i < $diffSize; $i++) {
  101107. if ($diff[$i][1] === 0) {
  101108. if ($capturing === \false) {
  101109. $capturing = \true;
  101110. $chunkStart = $i;
  101111. $chunkSize = 0;
  101112. } else {
  101113. $chunkSize++;
  101114. }
  101115. } elseif ($capturing !== \false) {
  101116. if ($chunkSize >= $lineThreshold) {
  101117. $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
  101118. }
  101119. $capturing = \false;
  101120. }
  101121. }
  101122. if ($capturing !== \false && $chunkSize >= $lineThreshold) {
  101123. $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
  101124. }
  101125. return $commonChunks;
  101126. }
  101127. }
  101128. <?php
  101129. declare (strict_types=1);
  101130. /*
  101131. * This file is part of sebastian/diff.
  101132. *
  101133. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101134. *
  101135. * For the full copyright and license information, please view the LICENSE
  101136. * file that was distributed with this source code.
  101137. */
  101138. namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
  101139. use function fclose;
  101140. use function fopen;
  101141. use function fwrite;
  101142. use function str_ends_with;
  101143. use function stream_get_contents;
  101144. use function substr;
  101145. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  101146. /**
  101147. * Builds a diff string representation in a loose unified diff format
  101148. * listing only changes lines. Does not include line numbers.
  101149. */
  101150. final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface
  101151. {
  101152. private string $header;
  101153. public function __construct(string $header = "--- Original\n+++ New\n")
  101154. {
  101155. $this->header = $header;
  101156. }
  101157. public function getDiff(array $diff): string
  101158. {
  101159. $buffer = fopen('php://memory', 'r+b');
  101160. if ('' !== $this->header) {
  101161. fwrite($buffer, $this->header);
  101162. if (!str_ends_with($this->header, "\n")) {
  101163. fwrite($buffer, "\n");
  101164. }
  101165. }
  101166. foreach ($diff as $diffEntry) {
  101167. if ($diffEntry[1] === Differ::ADDED) {
  101168. fwrite($buffer, '+' . $diffEntry[0]);
  101169. } elseif ($diffEntry[1] === Differ::REMOVED) {
  101170. fwrite($buffer, '-' . $diffEntry[0]);
  101171. } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) {
  101172. fwrite($buffer, ' ' . $diffEntry[0]);
  101173. continue;
  101174. // Warnings should not be tested for line break, it will always be there
  101175. } else {
  101176. /* Not changed (old) 0 */
  101177. continue;
  101178. // we didn't write the not-changed line, so do not add a line break either
  101179. }
  101180. $lc = substr($diffEntry[0], -1);
  101181. if ($lc !== "\n" && $lc !== "\r") {
  101182. fwrite($buffer, "\n");
  101183. // \No newline at end of file
  101184. }
  101185. }
  101186. $diff = stream_get_contents($buffer, -1, 0);
  101187. fclose($buffer);
  101188. return $diff;
  101189. }
  101190. }
  101191. <?php
  101192. declare (strict_types=1);
  101193. /*
  101194. * This file is part of sebastian/diff.
  101195. *
  101196. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101197. *
  101198. * For the full copyright and license information, please view the LICENSE
  101199. * file that was distributed with this source code.
  101200. */
  101201. namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
  101202. /**
  101203. * Defines how an output builder should take a generated
  101204. * diff array and return a string representation of that diff.
  101205. */
  101206. interface DiffOutputBuilderInterface
  101207. {
  101208. public function getDiff(array $diff): string;
  101209. }
  101210. <?php
  101211. declare (strict_types=1);
  101212. /*
  101213. * This file is part of sebastian/diff.
  101214. *
  101215. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101216. *
  101217. * For the full copyright and license information, please view the LICENSE
  101218. * file that was distributed with this source code.
  101219. */
  101220. namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
  101221. use function array_merge;
  101222. use function array_splice;
  101223. use function count;
  101224. use function fclose;
  101225. use function fopen;
  101226. use function fwrite;
  101227. use function is_bool;
  101228. use function is_int;
  101229. use function is_string;
  101230. use function max;
  101231. use function min;
  101232. use function sprintf;
  101233. use function stream_get_contents;
  101234. use function substr;
  101235. use PHPUnitPHAR\SebastianBergmann\Diff\ConfigurationException;
  101236. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  101237. /**
  101238. * Strict Unified diff output builder.
  101239. *
  101240. * Generates (strict) Unified diff's (unidiffs) with hunks.
  101241. */
  101242. final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface
  101243. {
  101244. private static array $default = [
  101245. 'collapseRanges' => \true,
  101246. // ranges of length one are rendered with the trailing `,1`
  101247. 'commonLineThreshold' => 6,
  101248. // number of same lines before ending a new hunk and creating a new one (if needed)
  101249. 'contextLines' => 3,
  101250. // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
  101251. 'fromFile' => null,
  101252. 'fromFileDate' => null,
  101253. 'toFile' => null,
  101254. 'toFileDate' => null,
  101255. ];
  101256. private bool $changed;
  101257. private bool $collapseRanges;
  101258. /**
  101259. * @psalm-var positive-int
  101260. */
  101261. private int $commonLineThreshold;
  101262. private string $header;
  101263. /**
  101264. * @psalm-var positive-int
  101265. */
  101266. private int $contextLines;
  101267. public function __construct(array $options = [])
  101268. {
  101269. $options = array_merge(self::$default, $options);
  101270. if (!is_bool($options['collapseRanges'])) {
  101271. throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']);
  101272. }
  101273. if (!is_int($options['contextLines']) || $options['contextLines'] < 0) {
  101274. throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']);
  101275. }
  101276. if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) {
  101277. throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']);
  101278. }
  101279. $this->assertString($options, 'fromFile');
  101280. $this->assertString($options, 'toFile');
  101281. $this->assertStringOrNull($options, 'fromFileDate');
  101282. $this->assertStringOrNull($options, 'toFileDate');
  101283. $this->header = sprintf("--- %s%s\n+++ %s%s\n", $options['fromFile'], null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'], $options['toFile'], null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate']);
  101284. $this->collapseRanges = $options['collapseRanges'];
  101285. $this->commonLineThreshold = $options['commonLineThreshold'];
  101286. $this->contextLines = $options['contextLines'];
  101287. }
  101288. public function getDiff(array $diff): string
  101289. {
  101290. if (0 === count($diff)) {
  101291. return '';
  101292. }
  101293. $this->changed = \false;
  101294. $buffer = fopen('php://memory', 'r+b');
  101295. fwrite($buffer, $this->header);
  101296. $this->writeDiffHunks($buffer, $diff);
  101297. if (!$this->changed) {
  101298. fclose($buffer);
  101299. return '';
  101300. }
  101301. $diff = stream_get_contents($buffer, -1, 0);
  101302. fclose($buffer);
  101303. // If the last char is not a linebreak: add it.
  101304. // This might happen when both the `from` and `to` do not have a trailing linebreak
  101305. $last = substr($diff, -1);
  101306. return "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
  101307. }
  101308. private function writeDiffHunks($output, array $diff): void
  101309. {
  101310. // detect "No newline at end of file" and insert into `$diff` if needed
  101311. $upperLimit = count($diff);
  101312. if (0 === $diff[$upperLimit - 1][1]) {
  101313. $lc = substr($diff[$upperLimit - 1][0], -1);
  101314. if ("\n" !== $lc) {
  101315. array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
  101316. }
  101317. } else {
  101318. // search back for the last `+` and `-` line,
  101319. // check if it has a trailing linebreak, else add a warning under it
  101320. $toFind = [1 => \true, 2 => \true];
  101321. for ($i = $upperLimit - 1; $i >= 0; $i--) {
  101322. if (isset($toFind[$diff[$i][1]])) {
  101323. unset($toFind[$diff[$i][1]]);
  101324. $lc = substr($diff[$i][0], -1);
  101325. if ("\n" !== $lc) {
  101326. array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
  101327. }
  101328. if (!count($toFind)) {
  101329. break;
  101330. }
  101331. }
  101332. }
  101333. }
  101334. // write hunks to output buffer
  101335. $cutOff = max($this->commonLineThreshold, $this->contextLines);
  101336. $hunkCapture = \false;
  101337. $sameCount = $toRange = $fromRange = 0;
  101338. $toStart = $fromStart = 1;
  101339. $i = 0;
  101340. /** @var int $i */
  101341. foreach ($diff as $i => $entry) {
  101342. if (0 === $entry[1]) {
  101343. // same
  101344. if (\false === $hunkCapture) {
  101345. $fromStart++;
  101346. $toStart++;
  101347. continue;
  101348. }
  101349. $sameCount++;
  101350. $toRange++;
  101351. $fromRange++;
  101352. if ($sameCount === $cutOff) {
  101353. $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
  101354. // note: $contextEndOffset = $this->contextLines;
  101355. //
  101356. // because we never go beyond the end of the diff.
  101357. // with the cutoff/contextlines here the follow is never true;
  101358. //
  101359. // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
  101360. // $contextEndOffset = count($diff) - 1;
  101361. // }
  101362. //
  101363. // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
  101364. $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
  101365. $fromStart += $fromRange;
  101366. $toStart += $toRange;
  101367. $hunkCapture = \false;
  101368. $sameCount = $toRange = $fromRange = 0;
  101369. }
  101370. continue;
  101371. }
  101372. $sameCount = 0;
  101373. if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
  101374. continue;
  101375. }
  101376. $this->changed = \true;
  101377. if (\false === $hunkCapture) {
  101378. $hunkCapture = $i;
  101379. }
  101380. if (Differ::ADDED === $entry[1]) {
  101381. // added
  101382. $toRange++;
  101383. }
  101384. if (Differ::REMOVED === $entry[1]) {
  101385. // removed
  101386. $fromRange++;
  101387. }
  101388. }
  101389. if (\false === $hunkCapture) {
  101390. return;
  101391. }
  101392. // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk,
  101393. // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
  101394. $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
  101395. // prevent trying to write out more common lines than there are in the diff _and_
  101396. // do not write more than configured through the context lines
  101397. $contextEndOffset = min($sameCount, $this->contextLines);
  101398. $fromRange -= $sameCount;
  101399. $toRange -= $sameCount;
  101400. $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
  101401. }
  101402. private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output): void
  101403. {
  101404. fwrite($output, '@@ -' . $fromStart);
  101405. if (!$this->collapseRanges || 1 !== $fromRange) {
  101406. fwrite($output, ',' . $fromRange);
  101407. }
  101408. fwrite($output, ' +' . $toStart);
  101409. if (!$this->collapseRanges || 1 !== $toRange) {
  101410. fwrite($output, ',' . $toRange);
  101411. }
  101412. fwrite($output, " @@\n");
  101413. for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) {
  101414. if ($diff[$i][1] === Differ::ADDED) {
  101415. $this->changed = \true;
  101416. fwrite($output, '+' . $diff[$i][0]);
  101417. } elseif ($diff[$i][1] === Differ::REMOVED) {
  101418. $this->changed = \true;
  101419. fwrite($output, '-' . $diff[$i][0]);
  101420. } elseif ($diff[$i][1] === Differ::OLD) {
  101421. fwrite($output, ' ' . $diff[$i][0]);
  101422. } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
  101423. $this->changed = \true;
  101424. fwrite($output, $diff[$i][0]);
  101425. }
  101426. // } elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package
  101427. // skip
  101428. // } else {
  101429. // unknown/invalid
  101430. // }
  101431. }
  101432. }
  101433. private function assertString(array $options, string $option): void
  101434. {
  101435. if (!is_string($options[$option])) {
  101436. throw new ConfigurationException($option, 'a string', $options[$option]);
  101437. }
  101438. }
  101439. private function assertStringOrNull(array $options, string $option): void
  101440. {
  101441. if (null !== $options[$option] && !is_string($options[$option])) {
  101442. throw new ConfigurationException($option, 'a string or <null>', $options[$option]);
  101443. }
  101444. }
  101445. }
  101446. <?php
  101447. declare (strict_types=1);
  101448. /*
  101449. * This file is part of sebastian/diff.
  101450. *
  101451. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101452. *
  101453. * For the full copyright and license information, please view the LICENSE
  101454. * file that was distributed with this source code.
  101455. */
  101456. namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
  101457. use function array_splice;
  101458. use function count;
  101459. use function fclose;
  101460. use function fopen;
  101461. use function fwrite;
  101462. use function max;
  101463. use function min;
  101464. use function str_ends_with;
  101465. use function stream_get_contents;
  101466. use function substr;
  101467. use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
  101468. /**
  101469. * Builds a diff string representation in unified diff format in chunks.
  101470. */
  101471. final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder
  101472. {
  101473. private bool $collapseRanges = \true;
  101474. private int $commonLineThreshold = 6;
  101475. /**
  101476. * @psalm-var positive-int
  101477. */
  101478. private int $contextLines = 3;
  101479. private string $header;
  101480. private bool $addLineNumbers;
  101481. public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = \false)
  101482. {
  101483. $this->header = $header;
  101484. $this->addLineNumbers = $addLineNumbers;
  101485. }
  101486. public function getDiff(array $diff): string
  101487. {
  101488. $buffer = fopen('php://memory', 'r+b');
  101489. if ('' !== $this->header) {
  101490. fwrite($buffer, $this->header);
  101491. if (!str_ends_with($this->header, "\n")) {
  101492. fwrite($buffer, "\n");
  101493. }
  101494. }
  101495. if (0 !== count($diff)) {
  101496. $this->writeDiffHunks($buffer, $diff);
  101497. }
  101498. $diff = stream_get_contents($buffer, -1, 0);
  101499. fclose($buffer);
  101500. // If the diff is non-empty and last char is not a linebreak: add it.
  101501. // This might happen when both the `from` and `to` do not have a trailing linebreak
  101502. $last = substr($diff, -1);
  101503. return '' !== $diff && "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
  101504. }
  101505. private function writeDiffHunks($output, array $diff): void
  101506. {
  101507. // detect "No newline at end of file" and insert into `$diff` if needed
  101508. $upperLimit = count($diff);
  101509. if (0 === $diff[$upperLimit - 1][1]) {
  101510. $lc = substr($diff[$upperLimit - 1][0], -1);
  101511. if ("\n" !== $lc) {
  101512. array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
  101513. }
  101514. } else {
  101515. // search back for the last `+` and `-` line,
  101516. // check if it has trailing linebreak, else add a warning under it
  101517. $toFind = [1 => \true, 2 => \true];
  101518. for ($i = $upperLimit - 1; $i >= 0; $i--) {
  101519. if (isset($toFind[$diff[$i][1]])) {
  101520. unset($toFind[$diff[$i][1]]);
  101521. $lc = substr($diff[$i][0], -1);
  101522. if ("\n" !== $lc) {
  101523. array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
  101524. }
  101525. if (!count($toFind)) {
  101526. break;
  101527. }
  101528. }
  101529. }
  101530. }
  101531. // write hunks to output buffer
  101532. $cutOff = max($this->commonLineThreshold, $this->contextLines);
  101533. $hunkCapture = \false;
  101534. $sameCount = $toRange = $fromRange = 0;
  101535. $toStart = $fromStart = 1;
  101536. $i = 0;
  101537. /** @var int $i */
  101538. foreach ($diff as $i => $entry) {
  101539. if (0 === $entry[1]) {
  101540. // same
  101541. if (\false === $hunkCapture) {
  101542. $fromStart++;
  101543. $toStart++;
  101544. continue;
  101545. }
  101546. $sameCount++;
  101547. $toRange++;
  101548. $fromRange++;
  101549. if ($sameCount === $cutOff) {
  101550. $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
  101551. // note: $contextEndOffset = $this->contextLines;
  101552. //
  101553. // because we never go beyond the end of the diff.
  101554. // with the cutoff/contextlines here the follow is never true;
  101555. //
  101556. // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
  101557. // $contextEndOffset = count($diff) - 1;
  101558. // }
  101559. //
  101560. // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
  101561. $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
  101562. $fromStart += $fromRange;
  101563. $toStart += $toRange;
  101564. $hunkCapture = \false;
  101565. $sameCount = $toRange = $fromRange = 0;
  101566. }
  101567. continue;
  101568. }
  101569. $sameCount = 0;
  101570. if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
  101571. continue;
  101572. }
  101573. if (\false === $hunkCapture) {
  101574. $hunkCapture = $i;
  101575. }
  101576. if (Differ::ADDED === $entry[1]) {
  101577. $toRange++;
  101578. }
  101579. if (Differ::REMOVED === $entry[1]) {
  101580. $fromRange++;
  101581. }
  101582. }
  101583. if (\false === $hunkCapture) {
  101584. return;
  101585. }
  101586. // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk,
  101587. // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
  101588. $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
  101589. // prevent trying to write out more common lines than there are in the diff _and_
  101590. // do not write more than configured through the context lines
  101591. $contextEndOffset = min($sameCount, $this->contextLines);
  101592. $fromRange -= $sameCount;
  101593. $toRange -= $sameCount;
  101594. $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
  101595. }
  101596. private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output): void
  101597. {
  101598. if ($this->addLineNumbers) {
  101599. fwrite($output, '@@ -' . $fromStart);
  101600. if (!$this->collapseRanges || 1 !== $fromRange) {
  101601. fwrite($output, ',' . $fromRange);
  101602. }
  101603. fwrite($output, ' +' . $toStart);
  101604. if (!$this->collapseRanges || 1 !== $toRange) {
  101605. fwrite($output, ',' . $toRange);
  101606. }
  101607. fwrite($output, " @@\n");
  101608. } else {
  101609. fwrite($output, "@@ @@\n");
  101610. }
  101611. for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) {
  101612. if ($diff[$i][1] === Differ::ADDED) {
  101613. fwrite($output, '+' . $diff[$i][0]);
  101614. } elseif ($diff[$i][1] === Differ::REMOVED) {
  101615. fwrite($output, '-' . $diff[$i][0]);
  101616. } elseif ($diff[$i][1] === Differ::OLD) {
  101617. fwrite($output, ' ' . $diff[$i][0]);
  101618. } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
  101619. fwrite($output, "\n");
  101620. // $diff[$i][0]
  101621. } else {
  101622. /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */
  101623. fwrite($output, ' ' . $diff[$i][0]);
  101624. }
  101625. }
  101626. }
  101627. }
  101628. <?php
  101629. declare (strict_types=1);
  101630. /*
  101631. * This file is part of sebastian/diff.
  101632. *
  101633. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101634. *
  101635. * For the full copyright and license information, please view the LICENSE
  101636. * file that was distributed with this source code.
  101637. */
  101638. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  101639. use function array_pop;
  101640. use function assert;
  101641. use function count;
  101642. use function max;
  101643. use function preg_match;
  101644. use function preg_split;
  101645. /**
  101646. * Unified diff parser.
  101647. */
  101648. final class Parser
  101649. {
  101650. /**
  101651. * @return Diff[]
  101652. */
  101653. public function parse(string $string): array
  101654. {
  101655. $lines = preg_split('(\r\n|\r|\n)', $string);
  101656. if (!empty($lines) && $lines[count($lines) - 1] === '') {
  101657. array_pop($lines);
  101658. }
  101659. $lineCount = count($lines);
  101660. $diffs = [];
  101661. $diff = null;
  101662. $collected = [];
  101663. for ($i = 0; $i < $lineCount; $i++) {
  101664. if (preg_match('#^---\h+"?(?P<file>[^\v\t"]+)#', $lines[$i], $fromMatch) && preg_match('#^\+\+\+\h+"?(?P<file>[^\v\t"]+)#', $lines[$i + 1], $toMatch)) {
  101665. if ($diff !== null) {
  101666. $this->parseFileDiff($diff, $collected);
  101667. $diffs[] = $diff;
  101668. $collected = [];
  101669. }
  101670. assert(!empty($fromMatch['file']));
  101671. assert(!empty($toMatch['file']));
  101672. $diff = new Diff($fromMatch['file'], $toMatch['file']);
  101673. $i++;
  101674. } else {
  101675. if (preg_match('/^(?:diff --git |index [\da-f.]+|[+-]{3} [ab])/', $lines[$i])) {
  101676. continue;
  101677. }
  101678. $collected[] = $lines[$i];
  101679. }
  101680. }
  101681. if ($diff !== null && count($collected)) {
  101682. $this->parseFileDiff($diff, $collected);
  101683. $diffs[] = $diff;
  101684. }
  101685. return $diffs;
  101686. }
  101687. private function parseFileDiff(Diff $diff, array $lines): void
  101688. {
  101689. $chunks = [];
  101690. $chunk = null;
  101691. $diffLines = [];
  101692. foreach ($lines as $line) {
  101693. if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match, \PREG_UNMATCHED_AS_NULL)) {
  101694. $chunk = new Chunk((int) $match['start'], isset($match['startrange']) ? max(0, (int) $match['startrange']) : 1, (int) $match['end'], isset($match['endrange']) ? max(0, (int) $match['endrange']) : 1);
  101695. $chunks[] = $chunk;
  101696. $diffLines = [];
  101697. continue;
  101698. }
  101699. if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
  101700. $type = Line::UNCHANGED;
  101701. if ($match['type'] === '+') {
  101702. $type = Line::ADDED;
  101703. } elseif ($match['type'] === '-') {
  101704. $type = Line::REMOVED;
  101705. }
  101706. $diffLines[] = new Line($type, $match['line']);
  101707. $chunk?->setLines($diffLines);
  101708. }
  101709. }
  101710. $diff->setChunks($chunks);
  101711. }
  101712. }
  101713. <?php
  101714. declare (strict_types=1);
  101715. /*
  101716. * This file is part of sebastian/diff.
  101717. *
  101718. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101719. *
  101720. * For the full copyright and license information, please view the LICENSE
  101721. * file that was distributed with this source code.
  101722. */
  101723. namespace PHPUnitPHAR\SebastianBergmann\Diff;
  101724. use function array_reverse;
  101725. use function count;
  101726. use function max;
  101727. use SplFixedArray;
  101728. final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
  101729. {
  101730. /**
  101731. * @inheritDoc
  101732. */
  101733. public function calculate(array $from, array $to): array
  101734. {
  101735. $common = [];
  101736. $fromLength = count($from);
  101737. $toLength = count($to);
  101738. $width = $fromLength + 1;
  101739. $matrix = new SplFixedArray($width * ($toLength + 1));
  101740. for ($i = 0; $i <= $fromLength; $i++) {
  101741. $matrix[$i] = 0;
  101742. }
  101743. for ($j = 0; $j <= $toLength; $j++) {
  101744. $matrix[$j * $width] = 0;
  101745. }
  101746. for ($i = 1; $i <= $fromLength; $i++) {
  101747. for ($j = 1; $j <= $toLength; $j++) {
  101748. $o = $j * $width + $i;
  101749. // don't use max() to avoid function call overhead
  101750. $firstOrLast = $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0;
  101751. if ($matrix[$o - 1] > $matrix[$o - $width]) {
  101752. if ($firstOrLast > $matrix[$o - 1]) {
  101753. $matrix[$o] = $firstOrLast;
  101754. } else {
  101755. $matrix[$o] = $matrix[$o - 1];
  101756. }
  101757. } else if ($firstOrLast > $matrix[$o - $width]) {
  101758. $matrix[$o] = $firstOrLast;
  101759. } else {
  101760. $matrix[$o] = $matrix[$o - $width];
  101761. }
  101762. }
  101763. }
  101764. $i = $fromLength;
  101765. $j = $toLength;
  101766. while ($i > 0 && $j > 0) {
  101767. if ($from[$i - 1] === $to[$j - 1]) {
  101768. $common[] = $from[$i - 1];
  101769. $i--;
  101770. $j--;
  101771. } else {
  101772. $o = $j * $width + $i;
  101773. if ($matrix[$o - $width] > $matrix[$o - 1]) {
  101774. $j--;
  101775. } else {
  101776. $i--;
  101777. }
  101778. }
  101779. }
  101780. return array_reverse($common);
  101781. }
  101782. }
  101783. <?php
  101784. declare (strict_types=1);
  101785. /*
  101786. * This file is part of sebastian/environment.
  101787. *
  101788. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101789. *
  101790. * For the full copyright and license information, please view the LICENSE
  101791. * file that was distributed with this source code.
  101792. */
  101793. namespace PHPUnitPHAR\SebastianBergmann\Environment;
  101794. use const DIRECTORY_SEPARATOR;
  101795. use const STDIN;
  101796. use const STDOUT;
  101797. use function defined;
  101798. use function fclose;
  101799. use function fstat;
  101800. use function function_exists;
  101801. use function getenv;
  101802. use function is_resource;
  101803. use function is_string;
  101804. use function posix_isatty;
  101805. use function preg_match;
  101806. use function proc_close;
  101807. use function proc_open;
  101808. use function sapi_windows_vt100_support;
  101809. use function shell_exec;
  101810. use function stream_get_contents;
  101811. use function stream_isatty;
  101812. use function trim;
  101813. final class Console
  101814. {
  101815. /**
  101816. * @var int
  101817. */
  101818. public const STDIN = 0;
  101819. /**
  101820. * @var int
  101821. */
  101822. public const STDOUT = 1;
  101823. /**
  101824. * @var int
  101825. */
  101826. public const STDERR = 2;
  101827. /**
  101828. * Returns true if STDOUT supports colorization.
  101829. *
  101830. * This code has been copied and adapted from
  101831. * Symfony\Component\Console\Output\StreamOutput.
  101832. */
  101833. public function hasColorSupport(): bool
  101834. {
  101835. if ('Hyper' === getenv('TERM_PROGRAM')) {
  101836. return \true;
  101837. }
  101838. if ($this->isWindows()) {
  101839. // @codeCoverageIgnoreStart
  101840. return defined('STDOUT') && function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT) || \false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
  101841. // @codeCoverageIgnoreEnd
  101842. }
  101843. if (!defined('STDOUT')) {
  101844. // @codeCoverageIgnoreStart
  101845. return \false;
  101846. // @codeCoverageIgnoreEnd
  101847. }
  101848. return $this->isInteractive(STDOUT);
  101849. }
  101850. /**
  101851. * Returns the number of columns of the terminal.
  101852. *
  101853. * @codeCoverageIgnore
  101854. */
  101855. public function getNumberOfColumns(): int
  101856. {
  101857. if (!$this->isInteractive(defined('STDIN') ? STDIN : self::STDIN)) {
  101858. return 80;
  101859. }
  101860. if ($this->isWindows()) {
  101861. return $this->getNumberOfColumnsWindows();
  101862. }
  101863. return $this->getNumberOfColumnsInteractive();
  101864. }
  101865. /**
  101866. * Returns if the file descriptor is an interactive terminal or not.
  101867. *
  101868. * Normally, we want to use a resource as a parameter, yet sadly it's not always available,
  101869. * eg when running code in interactive console (`php -a`), STDIN/STDOUT/STDERR constants are not defined.
  101870. *
  101871. * @param int|resource $fileDescriptor
  101872. */
  101873. public function isInteractive($fileDescriptor = self::STDOUT): bool
  101874. {
  101875. if (is_resource($fileDescriptor)) {
  101876. if (function_exists('stream_isatty') && @stream_isatty($fileDescriptor)) {
  101877. return \true;
  101878. }
  101879. if (function_exists('fstat')) {
  101880. $stat = @fstat(STDOUT);
  101881. return $stat && 020000 === ($stat['mode'] & 0170000);
  101882. }
  101883. return \false;
  101884. }
  101885. return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
  101886. }
  101887. private function isWindows(): bool
  101888. {
  101889. return DIRECTORY_SEPARATOR === '\\';
  101890. }
  101891. /**
  101892. * @codeCoverageIgnore
  101893. */
  101894. private function getNumberOfColumnsInteractive(): int
  101895. {
  101896. if (function_exists('shell_exec') && preg_match('#\d+ (\d+)#', shell_exec('stty size') ?: '', $match) === 1) {
  101897. if ((int) $match[1] > 0) {
  101898. return (int) $match[1];
  101899. }
  101900. }
  101901. if (function_exists('shell_exec') && preg_match('#columns = (\d+);#', shell_exec('stty') ?: '', $match) === 1) {
  101902. if ((int) $match[1] > 0) {
  101903. return (int) $match[1];
  101904. }
  101905. }
  101906. return 80;
  101907. }
  101908. /**
  101909. * @codeCoverageIgnore
  101910. */
  101911. private function getNumberOfColumnsWindows(): int
  101912. {
  101913. $ansicon = getenv('ANSICON');
  101914. $columns = 80;
  101915. if (is_string($ansicon) && preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim($ansicon), $matches)) {
  101916. $columns = (int) $matches[1];
  101917. } elseif (function_exists('proc_open')) {
  101918. $process = proc_open('mode CON', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, null, null, ['suppress_errors' => \true]);
  101919. if (is_resource($process)) {
  101920. $info = stream_get_contents($pipes[1]);
  101921. fclose($pipes[1]);
  101922. fclose($pipes[2]);
  101923. proc_close($process);
  101924. if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
  101925. $columns = (int) $matches[2];
  101926. }
  101927. }
  101928. }
  101929. return $columns - 1;
  101930. }
  101931. }
  101932. BSD 3-Clause License
  101933. Copyright (c) 2014-2024, Sebastian Bergmann
  101934. All rights reserved.
  101935. Redistribution and use in source and binary forms, with or without
  101936. modification, are permitted provided that the following conditions are met:
  101937. 1. Redistributions of source code must retain the above copyright notice, this
  101938. list of conditions and the following disclaimer.
  101939. 2. Redistributions in binary form must reproduce the above copyright notice,
  101940. this list of conditions and the following disclaimer in the documentation
  101941. and/or other materials provided with the distribution.
  101942. 3. Neither the name of the copyright holder nor the names of its
  101943. contributors may be used to endorse or promote products derived from
  101944. this software without specific prior written permission.
  101945. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  101946. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  101947. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  101948. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  101949. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  101950. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  101951. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  101952. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  101953. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  101954. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  101955. <?php
  101956. declare (strict_types=1);
  101957. /*
  101958. * This file is part of sebastian/environment.
  101959. *
  101960. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  101961. *
  101962. * For the full copyright and license information, please view the LICENSE
  101963. * file that was distributed with this source code.
  101964. */
  101965. namespace PHPUnitPHAR\SebastianBergmann\Environment;
  101966. use const PHP_BINARY;
  101967. use const PHP_BINDIR;
  101968. use const PHP_MAJOR_VERSION;
  101969. use const PHP_SAPI;
  101970. use const PHP_VERSION;
  101971. use function array_map;
  101972. use function array_merge;
  101973. use function escapeshellarg;
  101974. use function explode;
  101975. use function extension_loaded;
  101976. use function ini_get;
  101977. use function is_readable;
  101978. use function parse_ini_file;
  101979. use function php_ini_loaded_file;
  101980. use function php_ini_scanned_files;
  101981. use function phpversion;
  101982. use function sprintf;
  101983. use function strrpos;
  101984. final class Runtime
  101985. {
  101986. private static string $rawBinary;
  101987. private static bool $initialized = \false;
  101988. /**
  101989. * Returns true when Xdebug or PCOV is available or
  101990. * the runtime used is PHPDBG.
  101991. */
  101992. public function canCollectCodeCoverage(): bool
  101993. {
  101994. return $this->hasXdebug() || $this->hasPCOV() || $this->hasPHPDBGCodeCoverage();
  101995. }
  101996. /**
  101997. * Returns true when Zend OPcache is loaded, enabled,
  101998. * and is configured to discard comments.
  101999. */
  102000. public function discardsComments(): bool
  102001. {
  102002. if (!$this->isOpcacheActive()) {
  102003. return \false;
  102004. }
  102005. if (ini_get('opcache.save_comments') !== '0') {
  102006. return \false;
  102007. }
  102008. return \true;
  102009. }
  102010. /**
  102011. * Returns true when Zend OPcache is loaded, enabled,
  102012. * and is configured to perform just-in-time compilation.
  102013. */
  102014. public function performsJustInTimeCompilation(): bool
  102015. {
  102016. if (PHP_MAJOR_VERSION < 8) {
  102017. return \false;
  102018. }
  102019. if (!$this->isOpcacheActive()) {
  102020. return \false;
  102021. }
  102022. if (ini_get('opcache.jit_buffer_size') === '0') {
  102023. return \false;
  102024. }
  102025. $jit = ini_get('opcache.jit');
  102026. if ($jit === 'disable' || $jit === 'off') {
  102027. return \false;
  102028. }
  102029. if (strrpos($jit, '0') === 3) {
  102030. return \false;
  102031. }
  102032. return \true;
  102033. }
  102034. /**
  102035. * Returns the raw path to the binary of the current runtime.
  102036. */
  102037. public function getRawBinary(): string
  102038. {
  102039. if (self::$initialized) {
  102040. return self::$rawBinary;
  102041. }
  102042. if (PHP_BINARY !== '') {
  102043. self::$rawBinary = PHP_BINARY;
  102044. self::$initialized = \true;
  102045. return self::$rawBinary;
  102046. }
  102047. // @codeCoverageIgnoreStart
  102048. $possibleBinaryLocations = [PHP_BINDIR . '/php', PHP_BINDIR . '/php-cli.exe', PHP_BINDIR . '/php.exe'];
  102049. foreach ($possibleBinaryLocations as $binary) {
  102050. if (is_readable($binary)) {
  102051. self::$rawBinary = $binary;
  102052. self::$initialized = \true;
  102053. return self::$rawBinary;
  102054. }
  102055. }
  102056. self::$rawBinary = 'php';
  102057. self::$initialized = \true;
  102058. return self::$rawBinary;
  102059. // @codeCoverageIgnoreEnd
  102060. }
  102061. /**
  102062. * Returns the escaped path to the binary of the current runtime.
  102063. */
  102064. public function getBinary(): string
  102065. {
  102066. return escapeshellarg($this->getRawBinary());
  102067. }
  102068. public function getNameWithVersion(): string
  102069. {
  102070. return $this->getName() . ' ' . $this->getVersion();
  102071. }
  102072. public function getNameWithVersionAndCodeCoverageDriver(): string
  102073. {
  102074. if ($this->hasPCOV()) {
  102075. return sprintf('%s with PCOV %s', $this->getNameWithVersion(), phpversion('pcov'));
  102076. }
  102077. if ($this->hasXdebug()) {
  102078. return sprintf('%s with Xdebug %s', $this->getNameWithVersion(), phpversion('xdebug'));
  102079. }
  102080. return $this->getNameWithVersion();
  102081. }
  102082. public function getName(): string
  102083. {
  102084. if ($this->isPHPDBG()) {
  102085. // @codeCoverageIgnoreStart
  102086. return 'PHPDBG';
  102087. // @codeCoverageIgnoreEnd
  102088. }
  102089. return 'PHP';
  102090. }
  102091. public function getVendorUrl(): string
  102092. {
  102093. return 'https://www.php.net/';
  102094. }
  102095. public function getVersion(): string
  102096. {
  102097. return PHP_VERSION;
  102098. }
  102099. /**
  102100. * Returns true when the runtime used is PHP and Xdebug is loaded.
  102101. */
  102102. public function hasXdebug(): bool
  102103. {
  102104. return $this->isPHP() && extension_loaded('xdebug');
  102105. }
  102106. /**
  102107. * Returns true when the runtime used is PHP without the PHPDBG SAPI.
  102108. */
  102109. public function isPHP(): bool
  102110. {
  102111. return !$this->isPHPDBG();
  102112. }
  102113. /**
  102114. * Returns true when the runtime used is PHP with the PHPDBG SAPI.
  102115. */
  102116. public function isPHPDBG(): bool
  102117. {
  102118. return PHP_SAPI === 'phpdbg';
  102119. }
  102120. /**
  102121. * Returns true when the runtime used is PHP with the PHPDBG SAPI
  102122. * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
  102123. */
  102124. public function hasPHPDBGCodeCoverage(): bool
  102125. {
  102126. return $this->isPHPDBG();
  102127. }
  102128. /**
  102129. * Returns true when the runtime used is PHP with PCOV loaded and enabled.
  102130. */
  102131. public function hasPCOV(): bool
  102132. {
  102133. return $this->isPHP() && extension_loaded('pcov') && ini_get('pcov.enabled');
  102134. }
  102135. /**
  102136. * Parses the loaded php.ini file (if any) as well as all
  102137. * additional php.ini files from the additional ini dir for
  102138. * a list of all configuration settings loaded from files
  102139. * at startup. Then checks for each php.ini setting passed
  102140. * via the `$values` parameter whether this setting has
  102141. * been changed at runtime. Returns an array of strings
  102142. * where each string has the format `key=value` denoting
  102143. * the name of a changed php.ini setting with its new value.
  102144. *
  102145. * @return string[]
  102146. */
  102147. public function getCurrentSettings(array $values): array
  102148. {
  102149. $diff = [];
  102150. $files = [];
  102151. if ($file = php_ini_loaded_file()) {
  102152. $files[] = $file;
  102153. }
  102154. if ($scanned = php_ini_scanned_files()) {
  102155. $files = array_merge($files, array_map('trim', explode(",\n", $scanned)));
  102156. }
  102157. foreach ($files as $ini) {
  102158. $config = parse_ini_file($ini, \true);
  102159. foreach ($values as $value) {
  102160. $set = ini_get($value);
  102161. if (empty($set)) {
  102162. continue;
  102163. }
  102164. if (!isset($config[$value]) || $set !== $config[$value]) {
  102165. $diff[$value] = sprintf('%s=%s', $value, $set);
  102166. }
  102167. }
  102168. }
  102169. return $diff;
  102170. }
  102171. private function isOpcacheActive(): bool
  102172. {
  102173. if (!extension_loaded('Zend OPcache')) {
  102174. return \false;
  102175. }
  102176. if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ini_get('opcache.enable_cli') === '1') {
  102177. return \true;
  102178. }
  102179. if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' && ini_get('opcache.enable') === '1') {
  102180. return \true;
  102181. }
  102182. return \false;
  102183. }
  102184. }
  102185. <?php
  102186. declare (strict_types=1);
  102187. /*
  102188. * This file is part of sebastian/exporter.
  102189. *
  102190. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102191. *
  102192. * For the full copyright and license information, please view the LICENSE
  102193. * file that was distributed with this source code.
  102194. */
  102195. namespace PHPUnitPHAR\SebastianBergmann\Exporter;
  102196. use function bin2hex;
  102197. use function count;
  102198. use function get_resource_type;
  102199. use function gettype;
  102200. use function implode;
  102201. use function ini_get;
  102202. use function ini_set;
  102203. use function is_array;
  102204. use function is_float;
  102205. use function is_object;
  102206. use function is_resource;
  102207. use function is_string;
  102208. use function mb_strlen;
  102209. use function mb_substr;
  102210. use function preg_match;
  102211. use function spl_object_id;
  102212. use function sprintf;
  102213. use function str_repeat;
  102214. use function str_replace;
  102215. use function var_export;
  102216. use BackedEnum;
  102217. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  102218. use SplObjectStorage;
  102219. use UnitEnum;
  102220. final class Exporter
  102221. {
  102222. /**
  102223. * Exports a value as a string.
  102224. *
  102225. * The output of this method is similar to the output of print_r(), but
  102226. * improved in various aspects:
  102227. *
  102228. * - NULL is rendered as "null" (instead of "")
  102229. * - TRUE is rendered as "true" (instead of "1")
  102230. * - FALSE is rendered as "false" (instead of "")
  102231. * - Strings are always quoted with single quotes
  102232. * - Carriage returns and newlines are normalized to \n
  102233. * - Recursion and repeated rendering is treated properly
  102234. */
  102235. public function export(mixed $value, int $indentation = 0): string
  102236. {
  102237. return $this->recursiveExport($value, $indentation);
  102238. }
  102239. public function shortenedRecursiveExport(array &$data, ?Context $context = null): string
  102240. {
  102241. $result = [];
  102242. $exporter = new self();
  102243. if (!$context) {
  102244. $context = new Context();
  102245. }
  102246. $array = $data;
  102247. /* @noinspection UnusedFunctionResultInspection */
  102248. $context->add($data);
  102249. foreach ($array as $key => $value) {
  102250. if (is_array($value)) {
  102251. if ($context->contains($data[$key]) !== \false) {
  102252. $result[] = '*RECURSION*';
  102253. } else {
  102254. $result[] = sprintf('[%s]', $this->shortenedRecursiveExport($data[$key], $context));
  102255. }
  102256. } else {
  102257. $result[] = $exporter->shortenedExport($value);
  102258. }
  102259. }
  102260. return implode(', ', $result);
  102261. }
  102262. /**
  102263. * Exports a value into a single-line string.
  102264. *
  102265. * The output of this method is similar to the output of
  102266. * SebastianBergmann\Exporter\Exporter::export().
  102267. *
  102268. * Newlines are replaced by the visible string '\n'.
  102269. * Contents of arrays and objects (if any) are replaced by '...'.
  102270. */
  102271. public function shortenedExport(mixed $value): string
  102272. {
  102273. if (is_string($value)) {
  102274. $string = str_replace("\n", '', $this->export($value));
  102275. if (mb_strlen($string) > 40) {
  102276. return mb_substr($string, 0, 30) . '...' . mb_substr($string, -7);
  102277. }
  102278. return $string;
  102279. }
  102280. if ($value instanceof BackedEnum) {
  102281. return sprintf('%s Enum (%s, %s)', $value::class, $value->name, $this->export($value->value));
  102282. }
  102283. if ($value instanceof UnitEnum) {
  102284. return sprintf('%s Enum (%s)', $value::class, $value->name);
  102285. }
  102286. if (is_object($value)) {
  102287. return sprintf('%s Object (%s)', $value::class, count($this->toArray($value)) > 0 ? '...' : '');
  102288. }
  102289. if (is_array($value)) {
  102290. return sprintf('[%s]', count($value) > 0 ? '...' : '');
  102291. }
  102292. return $this->export($value);
  102293. }
  102294. /**
  102295. * Converts an object to an array containing all of its private, protected
  102296. * and public properties.
  102297. */
  102298. public function toArray(mixed $value): array
  102299. {
  102300. if (!is_object($value)) {
  102301. return (array) $value;
  102302. }
  102303. $array = [];
  102304. foreach ((array) $value as $key => $val) {
  102305. // Exception traces commonly reference hundreds to thousands of
  102306. // objects currently loaded in memory. Including them in the result
  102307. // has a severe negative performance impact.
  102308. if ("\x00Error\x00trace" === $key || "\x00Exception\x00trace" === $key) {
  102309. continue;
  102310. }
  102311. // properties are transformed to keys in the following way:
  102312. // private $propertyName => "\0ClassName\0propertyName"
  102313. // protected $propertyName => "\0*\0propertyName"
  102314. // public $propertyName => "propertyName"
  102315. if (preg_match('/^\0.+\0(.+)$/', (string) $key, $matches)) {
  102316. $key = $matches[1];
  102317. }
  102318. // See https://github.com/php/php-src/commit/5721132
  102319. if ($key === "\x00gcdata") {
  102320. continue;
  102321. }
  102322. $array[$key] = $val;
  102323. }
  102324. // Some internal classes like SplObjectStorage do not work with the
  102325. // above (fast) mechanism nor with reflection in Zend.
  102326. // Format the output similarly to print_r() in this case
  102327. if ($value instanceof SplObjectStorage) {
  102328. foreach ($value as $_value) {
  102329. $array['Object #' . spl_object_id($_value)] = ['obj' => $_value, 'inf' => $value->getInfo()];
  102330. }
  102331. $value->rewind();
  102332. }
  102333. return $array;
  102334. }
  102335. private function recursiveExport(mixed &$value, int $indentation, ?Context $processed = null): string
  102336. {
  102337. if ($value === null) {
  102338. return 'null';
  102339. }
  102340. if ($value === \true) {
  102341. return 'true';
  102342. }
  102343. if ($value === \false) {
  102344. return 'false';
  102345. }
  102346. if (is_float($value)) {
  102347. $precisionBackup = ini_get('precision');
  102348. ini_set('precision', '-1');
  102349. try {
  102350. $valueStr = (string) $value;
  102351. if ((string) (int) $value === $valueStr) {
  102352. return $valueStr . '.0';
  102353. }
  102354. return $valueStr;
  102355. } finally {
  102356. ini_set('precision', $precisionBackup);
  102357. }
  102358. }
  102359. if (gettype($value) === 'resource (closed)') {
  102360. return 'resource (closed)';
  102361. }
  102362. if (is_resource($value)) {
  102363. return sprintf('resource(%d) of type (%s)', $value, get_resource_type($value));
  102364. }
  102365. if ($value instanceof BackedEnum) {
  102366. return sprintf('%s Enum #%d (%s, %s)', $value::class, spl_object_id($value), $value->name, $this->export($value->value, $indentation));
  102367. }
  102368. if ($value instanceof UnitEnum) {
  102369. return sprintf('%s Enum #%d (%s)', $value::class, spl_object_id($value), $value->name);
  102370. }
  102371. if (is_string($value)) {
  102372. // Match for most non-printable chars somewhat taking multibyte chars into account
  102373. if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) {
  102374. return 'Binary String: 0x' . bin2hex($value);
  102375. }
  102376. return "'" . str_replace('<lf>', "\n", str_replace(["\r\n", "\n\r", "\r", "\n"], ['\r\n<lf>', '\n\r<lf>', '\r<lf>', '\n<lf>'], $value)) . "'";
  102377. }
  102378. $whitespace = str_repeat(' ', 4 * $indentation);
  102379. if (!$processed) {
  102380. $processed = new Context();
  102381. }
  102382. if (is_array($value)) {
  102383. if (($key = $processed->contains($value)) !== \false) {
  102384. return 'Array &' . $key;
  102385. }
  102386. $array = $value;
  102387. $key = $processed->add($value);
  102388. $values = '';
  102389. if (count($array) > 0) {
  102390. foreach ($array as $k => $v) {
  102391. $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($value[$k], $indentation + 1, $processed) . ",\n";
  102392. }
  102393. $values = "\n" . $values . $whitespace;
  102394. }
  102395. return 'Array &' . (string) $key . ' [' . $values . ']';
  102396. }
  102397. if (is_object($value)) {
  102398. $class = $value::class;
  102399. if ($processed->contains($value)) {
  102400. return $class . ' Object #' . spl_object_id($value);
  102401. }
  102402. $processed->add($value);
  102403. $values = '';
  102404. $array = $this->toArray($value);
  102405. if (count($array) > 0) {
  102406. foreach ($array as $k => $v) {
  102407. $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($v, $indentation + 1, $processed) . ",\n";
  102408. }
  102409. $values = "\n" . $values . $whitespace;
  102410. }
  102411. return $class . ' Object #' . spl_object_id($value) . ' (' . $values . ')';
  102412. }
  102413. return var_export($value, \true);
  102414. }
  102415. }
  102416. BSD 3-Clause License
  102417. Copyright (c) 2002-2024, Sebastian Bergmann
  102418. All rights reserved.
  102419. Redistribution and use in source and binary forms, with or without
  102420. modification, are permitted provided that the following conditions are met:
  102421. 1. Redistributions of source code must retain the above copyright notice, this
  102422. list of conditions and the following disclaimer.
  102423. 2. Redistributions in binary form must reproduce the above copyright notice,
  102424. this list of conditions and the following disclaimer in the documentation
  102425. and/or other materials provided with the distribution.
  102426. 3. Neither the name of the copyright holder nor the names of its
  102427. contributors may be used to endorse or promote products derived from
  102428. this software without specific prior written permission.
  102429. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  102430. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  102431. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  102432. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  102433. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  102434. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  102435. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  102436. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  102437. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  102438. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  102439. <?php
  102440. declare (strict_types=1);
  102441. /*
  102442. * This file is part of sebastian/global-state.
  102443. *
  102444. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102445. *
  102446. * For the full copyright and license information, please view the LICENSE
  102447. * file that was distributed with this source code.
  102448. */
  102449. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  102450. use const PHP_EOL;
  102451. use function is_array;
  102452. use function is_scalar;
  102453. use function serialize;
  102454. use function sprintf;
  102455. use function var_export;
  102456. final class CodeExporter
  102457. {
  102458. public function constants(Snapshot $snapshot): string
  102459. {
  102460. $result = '';
  102461. foreach ($snapshot->constants() as $name => $value) {
  102462. $result .= sprintf('if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", $name, $name, $this->exportVariable($value));
  102463. }
  102464. return $result;
  102465. }
  102466. public function globalVariables(Snapshot $snapshot): string
  102467. {
  102468. $result = <<<'EOT'
  102469. call_user_func(
  102470. function ()
  102471. {
  102472. foreach (array_keys($GLOBALS) as $key) {
  102473. unset($GLOBALS[$key]);
  102474. }
  102475. }
  102476. );
  102477. EOT;
  102478. foreach ($snapshot->globalVariables() as $name => $value) {
  102479. $result .= sprintf('$GLOBALS[%s] = %s;' . PHP_EOL, $this->exportVariable($name), $this->exportVariable($value));
  102480. }
  102481. return $result;
  102482. }
  102483. public function iniSettings(Snapshot $snapshot): string
  102484. {
  102485. $result = '';
  102486. foreach ($snapshot->iniSettings() as $key => $value) {
  102487. $result .= sprintf('@ini_set(%s, %s);' . "\n", $this->exportVariable($key), $this->exportVariable($value));
  102488. }
  102489. return $result;
  102490. }
  102491. private function exportVariable(mixed $variable): string
  102492. {
  102493. if (is_scalar($variable) || null === $variable || is_array($variable) && $this->arrayOnlyContainsScalars($variable)) {
  102494. return var_export($variable, \true);
  102495. }
  102496. return 'unserialize(' . var_export(serialize($variable), \true) . ')';
  102497. }
  102498. private function arrayOnlyContainsScalars(array $array): bool
  102499. {
  102500. $result = \true;
  102501. foreach ($array as $element) {
  102502. if (is_array($element)) {
  102503. $result = $this->arrayOnlyContainsScalars($element);
  102504. } elseif (!is_scalar($element) && null !== $element) {
  102505. $result = \false;
  102506. }
  102507. if ($result === \false) {
  102508. break;
  102509. }
  102510. }
  102511. return $result;
  102512. }
  102513. }
  102514. <?php
  102515. declare (strict_types=1);
  102516. /*
  102517. * This file is part of sebastian/global-state.
  102518. *
  102519. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102520. *
  102521. * For the full copyright and license information, please view the LICENSE
  102522. * file that was distributed with this source code.
  102523. */
  102524. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  102525. use function in_array;
  102526. use function str_starts_with;
  102527. use ReflectionClass;
  102528. final class ExcludeList
  102529. {
  102530. private array $globalVariables = [];
  102531. private array $classes = [];
  102532. private array $classNamePrefixes = [];
  102533. private array $parentClasses = [];
  102534. private array $interfaces = [];
  102535. private array $staticProperties = [];
  102536. public function addGlobalVariable(string $variableName): void
  102537. {
  102538. $this->globalVariables[$variableName] = \true;
  102539. }
  102540. public function addClass(string $className): void
  102541. {
  102542. $this->classes[] = $className;
  102543. }
  102544. public function addSubclassesOf(string $className): void
  102545. {
  102546. $this->parentClasses[] = $className;
  102547. }
  102548. public function addImplementorsOf(string $interfaceName): void
  102549. {
  102550. $this->interfaces[] = $interfaceName;
  102551. }
  102552. public function addClassNamePrefix(string $classNamePrefix): void
  102553. {
  102554. $this->classNamePrefixes[] = $classNamePrefix;
  102555. }
  102556. public function addStaticProperty(string $className, string $propertyName): void
  102557. {
  102558. if (!isset($this->staticProperties[$className])) {
  102559. $this->staticProperties[$className] = [];
  102560. }
  102561. $this->staticProperties[$className][$propertyName] = \true;
  102562. }
  102563. public function isGlobalVariableExcluded(string $variableName): bool
  102564. {
  102565. return isset($this->globalVariables[$variableName]);
  102566. }
  102567. /**
  102568. * @psalm-param class-string $className
  102569. */
  102570. public function isStaticPropertyExcluded(string $className, string $propertyName): bool
  102571. {
  102572. if (in_array($className, $this->classes, \true)) {
  102573. return \true;
  102574. }
  102575. foreach ($this->classNamePrefixes as $prefix) {
  102576. if (str_starts_with($className, $prefix)) {
  102577. return \true;
  102578. }
  102579. }
  102580. $class = new ReflectionClass($className);
  102581. foreach ($this->parentClasses as $type) {
  102582. if ($class->isSubclassOf($type)) {
  102583. return \true;
  102584. }
  102585. }
  102586. foreach ($this->interfaces as $type) {
  102587. if ($class->implementsInterface($type)) {
  102588. return \true;
  102589. }
  102590. }
  102591. return isset($this->staticProperties[$className][$propertyName]);
  102592. }
  102593. }
  102594. BSD 3-Clause License
  102595. Copyright (c) 2001-2024, Sebastian Bergmann
  102596. All rights reserved.
  102597. Redistribution and use in source and binary forms, with or without
  102598. modification, are permitted provided that the following conditions are met:
  102599. 1. Redistributions of source code must retain the above copyright notice, this
  102600. list of conditions and the following disclaimer.
  102601. 2. Redistributions in binary form must reproduce the above copyright notice,
  102602. this list of conditions and the following disclaimer in the documentation
  102603. and/or other materials provided with the distribution.
  102604. 3. Neither the name of the copyright holder nor the names of its
  102605. contributors may be used to endorse or promote products derived from
  102606. this software without specific prior written permission.
  102607. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  102608. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  102609. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  102610. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  102611. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  102612. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  102613. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  102614. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  102615. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  102616. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  102617. <?php
  102618. declare (strict_types=1);
  102619. /*
  102620. * This file is part of sebastian/global-state.
  102621. *
  102622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102623. *
  102624. * For the full copyright and license information, please view the LICENSE
  102625. * file that was distributed with this source code.
  102626. */
  102627. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  102628. use function array_diff;
  102629. use function array_key_exists;
  102630. use function array_keys;
  102631. use function array_merge;
  102632. use function in_array;
  102633. use function is_array;
  102634. use ReflectionClass;
  102635. use ReflectionProperty;
  102636. final class Restorer
  102637. {
  102638. public function restoreGlobalVariables(Snapshot $snapshot): void
  102639. {
  102640. $superGlobalArrays = $snapshot->superGlobalArrays();
  102641. foreach ($superGlobalArrays as $superGlobalArray) {
  102642. $this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
  102643. }
  102644. $globalVariables = $snapshot->globalVariables();
  102645. foreach (array_keys($GLOBALS) as $key) {
  102646. if ($key !== 'GLOBALS' && !in_array($key, $superGlobalArrays, \true) && !$snapshot->excludeList()->isGlobalVariableExcluded($key)) {
  102647. if (array_key_exists($key, $globalVariables)) {
  102648. $GLOBALS[$key] = $globalVariables[$key];
  102649. } else {
  102650. unset($GLOBALS[$key]);
  102651. }
  102652. }
  102653. }
  102654. }
  102655. public function restoreStaticProperties(Snapshot $snapshot): void
  102656. {
  102657. $current = new Snapshot($snapshot->excludeList(), \false, \false, \false, \false, \true, \false, \false, \false, \false);
  102658. $newClasses = array_diff($current->classes(), $snapshot->classes());
  102659. unset($current);
  102660. foreach ($snapshot->staticProperties() as $className => $staticProperties) {
  102661. foreach ($staticProperties as $name => $value) {
  102662. $reflector = new ReflectionProperty($className, $name);
  102663. $reflector->setValue(null, $value);
  102664. }
  102665. }
  102666. foreach ($newClasses as $className) {
  102667. $class = new ReflectionClass($className);
  102668. $defaults = $class->getDefaultProperties();
  102669. foreach ($class->getProperties() as $property) {
  102670. if (!$property->isStatic()) {
  102671. continue;
  102672. }
  102673. $name = $property->getName();
  102674. if ($snapshot->excludeList()->isStaticPropertyExcluded($className, $name)) {
  102675. continue;
  102676. }
  102677. if (!isset($defaults[$name])) {
  102678. continue;
  102679. }
  102680. $property->setValue(null, $defaults[$name]);
  102681. }
  102682. }
  102683. }
  102684. private function restoreSuperGlobalArray(Snapshot $snapshot, string $superGlobalArray): void
  102685. {
  102686. $superGlobalVariables = $snapshot->superGlobalVariables();
  102687. if (isset($GLOBALS[$superGlobalArray], $superGlobalVariables[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
  102688. $keys = array_keys(array_merge($GLOBALS[$superGlobalArray], $superGlobalVariables[$superGlobalArray]));
  102689. foreach ($keys as $key) {
  102690. if (isset($superGlobalVariables[$superGlobalArray][$key])) {
  102691. $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
  102692. } else {
  102693. unset($GLOBALS[$superGlobalArray][$key]);
  102694. }
  102695. }
  102696. }
  102697. }
  102698. }
  102699. <?php
  102700. declare (strict_types=1);
  102701. /*
  102702. * This file is part of sebastian/global-state.
  102703. *
  102704. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102705. *
  102706. * For the full copyright and license information, please view the LICENSE
  102707. * file that was distributed with this source code.
  102708. */
  102709. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  102710. use function array_keys;
  102711. use function array_merge;
  102712. use function array_reverse;
  102713. use function assert;
  102714. use function func_get_args;
  102715. use function get_declared_classes;
  102716. use function get_declared_interfaces;
  102717. use function get_declared_traits;
  102718. use function get_defined_constants;
  102719. use function get_defined_functions;
  102720. use function get_included_files;
  102721. use function in_array;
  102722. use function ini_get_all;
  102723. use function is_array;
  102724. use function is_object;
  102725. use function is_resource;
  102726. use function is_scalar;
  102727. use function serialize;
  102728. use function unserialize;
  102729. use ReflectionClass;
  102730. use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
  102731. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  102732. use Throwable;
  102733. /**
  102734. * A snapshot of global state.
  102735. */
  102736. class Snapshot
  102737. {
  102738. private ExcludeList $excludeList;
  102739. private array $globalVariables = [];
  102740. private array $superGlobalArrays = [];
  102741. private array $superGlobalVariables = [];
  102742. private array $staticProperties = [];
  102743. private array $iniSettings = [];
  102744. private array $includedFiles = [];
  102745. private array $constants = [];
  102746. private array $functions = [];
  102747. private array $interfaces = [];
  102748. private array $classes = [];
  102749. private array $traits = [];
  102750. public function __construct(?ExcludeList $excludeList = null, bool $includeGlobalVariables = \true, bool $includeStaticProperties = \true, bool $includeConstants = \true, bool $includeFunctions = \true, bool $includeClasses = \true, bool $includeInterfaces = \true, bool $includeTraits = \true, bool $includeIniSettings = \true, bool $includeIncludedFiles = \true)
  102751. {
  102752. $this->excludeList = $excludeList ?: new ExcludeList();
  102753. if ($includeConstants) {
  102754. $this->snapshotConstants();
  102755. }
  102756. if ($includeFunctions) {
  102757. $this->snapshotFunctions();
  102758. }
  102759. if ($includeClasses || $includeStaticProperties) {
  102760. $this->snapshotClasses();
  102761. }
  102762. if ($includeInterfaces) {
  102763. $this->snapshotInterfaces();
  102764. }
  102765. if ($includeGlobalVariables) {
  102766. $this->setupSuperGlobalArrays();
  102767. $this->snapshotGlobals();
  102768. }
  102769. if ($includeStaticProperties) {
  102770. $this->snapshotStaticProperties();
  102771. }
  102772. if ($includeIniSettings) {
  102773. $this->iniSettings = ini_get_all(null, \false);
  102774. }
  102775. if ($includeIncludedFiles) {
  102776. $this->includedFiles = get_included_files();
  102777. }
  102778. if ($includeTraits) {
  102779. $this->traits = get_declared_traits();
  102780. }
  102781. }
  102782. public function excludeList(): ExcludeList
  102783. {
  102784. return $this->excludeList;
  102785. }
  102786. public function globalVariables(): array
  102787. {
  102788. return $this->globalVariables;
  102789. }
  102790. public function superGlobalVariables(): array
  102791. {
  102792. return $this->superGlobalVariables;
  102793. }
  102794. public function superGlobalArrays(): array
  102795. {
  102796. return $this->superGlobalArrays;
  102797. }
  102798. public function staticProperties(): array
  102799. {
  102800. return $this->staticProperties;
  102801. }
  102802. public function iniSettings(): array
  102803. {
  102804. return $this->iniSettings;
  102805. }
  102806. public function includedFiles(): array
  102807. {
  102808. return $this->includedFiles;
  102809. }
  102810. public function constants(): array
  102811. {
  102812. return $this->constants;
  102813. }
  102814. public function functions(): array
  102815. {
  102816. return $this->functions;
  102817. }
  102818. public function interfaces(): array
  102819. {
  102820. return $this->interfaces;
  102821. }
  102822. public function classes(): array
  102823. {
  102824. return $this->classes;
  102825. }
  102826. public function traits(): array
  102827. {
  102828. return $this->traits;
  102829. }
  102830. private function snapshotConstants(): void
  102831. {
  102832. $constants = get_defined_constants(\true);
  102833. if (isset($constants['user'])) {
  102834. $this->constants = $constants['user'];
  102835. }
  102836. }
  102837. private function snapshotFunctions(): void
  102838. {
  102839. $functions = get_defined_functions();
  102840. $this->functions = $functions['user'];
  102841. }
  102842. private function snapshotClasses(): void
  102843. {
  102844. foreach (array_reverse(get_declared_classes()) as $className) {
  102845. $class = new ReflectionClass($className);
  102846. if (!$class->isUserDefined()) {
  102847. break;
  102848. }
  102849. $this->classes[] = $className;
  102850. }
  102851. $this->classes = array_reverse($this->classes);
  102852. }
  102853. private function snapshotInterfaces(): void
  102854. {
  102855. foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
  102856. $class = new ReflectionClass($interfaceName);
  102857. if (!$class->isUserDefined()) {
  102858. break;
  102859. }
  102860. $this->interfaces[] = $interfaceName;
  102861. }
  102862. $this->interfaces = array_reverse($this->interfaces);
  102863. }
  102864. private function snapshotGlobals(): void
  102865. {
  102866. $superGlobalArrays = $this->superGlobalArrays();
  102867. foreach ($superGlobalArrays as $superGlobalArray) {
  102868. $this->snapshotSuperGlobalArray($superGlobalArray);
  102869. }
  102870. foreach (array_keys($GLOBALS) as $key) {
  102871. if ($key !== 'GLOBALS' && !in_array($key, $superGlobalArrays, \true) && $this->canBeSerialized($GLOBALS[$key]) && !$this->excludeList->isGlobalVariableExcluded($key)) {
  102872. /* @noinspection UnserializeExploitsInspection */
  102873. $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
  102874. }
  102875. }
  102876. }
  102877. private function snapshotSuperGlobalArray(string $superGlobalArray): void
  102878. {
  102879. $this->superGlobalVariables[$superGlobalArray] = [];
  102880. if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
  102881. foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
  102882. /* @noinspection UnserializeExploitsInspection */
  102883. $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
  102884. }
  102885. }
  102886. }
  102887. private function snapshotStaticProperties(): void
  102888. {
  102889. foreach ($this->classes as $className) {
  102890. $class = new ReflectionClass($className);
  102891. $snapshot = [];
  102892. foreach ($class->getProperties() as $property) {
  102893. if ($property->isStatic()) {
  102894. $name = $property->getName();
  102895. if ($this->excludeList->isStaticPropertyExcluded($className, $name)) {
  102896. continue;
  102897. }
  102898. if (!$property->isInitialized()) {
  102899. continue;
  102900. }
  102901. $value = $property->getValue();
  102902. if ($this->canBeSerialized($value)) {
  102903. /* @noinspection UnserializeExploitsInspection */
  102904. $snapshot[$name] = unserialize(serialize($value));
  102905. }
  102906. }
  102907. }
  102908. if (!empty($snapshot)) {
  102909. $this->staticProperties[$className] = $snapshot;
  102910. }
  102911. }
  102912. }
  102913. private function setupSuperGlobalArrays(): void
  102914. {
  102915. $this->superGlobalArrays = ['_ENV', '_POST', '_GET', '_COOKIE', '_SERVER', '_FILES', '_REQUEST'];
  102916. }
  102917. private function canBeSerialized(mixed $variable): bool
  102918. {
  102919. if (is_scalar($variable) || $variable === null) {
  102920. return \true;
  102921. }
  102922. if (is_resource($variable)) {
  102923. return \false;
  102924. }
  102925. foreach ($this->enumerateObjectsAndResources($variable) as $value) {
  102926. if (is_resource($value)) {
  102927. return \false;
  102928. }
  102929. if (is_object($value)) {
  102930. $class = new ReflectionClass($value);
  102931. if ($class->isAnonymous()) {
  102932. return \false;
  102933. }
  102934. try {
  102935. @serialize($value);
  102936. } catch (Throwable $t) {
  102937. return \false;
  102938. }
  102939. }
  102940. }
  102941. return \true;
  102942. }
  102943. private function enumerateObjectsAndResources(mixed $variable): array
  102944. {
  102945. if (isset(func_get_args()[1])) {
  102946. $processed = func_get_args()[1];
  102947. } else {
  102948. $processed = new Context();
  102949. }
  102950. assert($processed instanceof Context);
  102951. $result = [];
  102952. if ($processed->contains($variable)) {
  102953. return $result;
  102954. }
  102955. $array = $variable;
  102956. /* @noinspection UnusedFunctionResultInspection */
  102957. $processed->add($variable);
  102958. if (is_array($variable)) {
  102959. foreach ($array as $element) {
  102960. if (!is_array($element) && !is_object($element) && !is_resource($element)) {
  102961. continue;
  102962. }
  102963. if (!is_resource($element)) {
  102964. /** @noinspection SlowArrayOperationsInLoopInspection */
  102965. $result = array_merge($result, $this->enumerateObjectsAndResources($element, $processed));
  102966. } else {
  102967. $result[] = $element;
  102968. }
  102969. }
  102970. } else {
  102971. $result[] = $variable;
  102972. foreach ((new ObjectReflector())->getProperties($variable) as $value) {
  102973. if (!is_array($value) && !is_object($value) && !is_resource($value)) {
  102974. continue;
  102975. }
  102976. if (!is_resource($value)) {
  102977. /** @noinspection SlowArrayOperationsInLoopInspection */
  102978. $result = array_merge($result, $this->enumerateObjectsAndResources($value, $processed));
  102979. } else {
  102980. $result[] = $value;
  102981. }
  102982. }
  102983. }
  102984. return $result;
  102985. }
  102986. }
  102987. <?php
  102988. declare (strict_types=1);
  102989. /*
  102990. * This file is part of sebastian/global-state.
  102991. *
  102992. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  102993. *
  102994. * For the full copyright and license information, please view the LICENSE
  102995. * file that was distributed with this source code.
  102996. */
  102997. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  102998. use Throwable;
  102999. interface Exception extends Throwable
  103000. {
  103001. }
  103002. <?php
  103003. declare (strict_types=1);
  103004. /*
  103005. * This file is part of sebastian/global-state.
  103006. *
  103007. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103008. *
  103009. * For the full copyright and license information, please view the LICENSE
  103010. * file that was distributed with this source code.
  103011. */
  103012. namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
  103013. final class RuntimeException extends \RuntimeException implements Exception
  103014. {
  103015. }
  103016. <?php
  103017. declare (strict_types=1);
  103018. /*
  103019. * This file is part of sebastian/lines-of-code.
  103020. *
  103021. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103022. *
  103023. * For the full copyright and license information, please view the LICENSE
  103024. * file that was distributed with this source code.
  103025. */
  103026. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103027. use function assert;
  103028. use function file_get_contents;
  103029. use function substr_count;
  103030. use PHPUnitPHAR\PhpParser\Error;
  103031. use PHPUnitPHAR\PhpParser\Node;
  103032. use PHPUnitPHAR\PhpParser\NodeTraverser;
  103033. use PHPUnitPHAR\PhpParser\ParserFactory;
  103034. final class Counter
  103035. {
  103036. /**
  103037. * @throws RuntimeException
  103038. */
  103039. public function countInSourceFile(string $sourceFile): LinesOfCode
  103040. {
  103041. return $this->countInSourceString(file_get_contents($sourceFile));
  103042. }
  103043. /**
  103044. * @throws RuntimeException
  103045. */
  103046. public function countInSourceString(string $source): LinesOfCode
  103047. {
  103048. $linesOfCode = substr_count($source, "\n");
  103049. if ($linesOfCode === 0 && !empty($source)) {
  103050. $linesOfCode = 1;
  103051. }
  103052. assert($linesOfCode >= 0);
  103053. try {
  103054. $nodes = (new ParserFactory())->createForHostVersion()->parse($source);
  103055. assert($nodes !== null);
  103056. return $this->countInAbstractSyntaxTree($linesOfCode, $nodes);
  103057. // @codeCoverageIgnoreStart
  103058. } catch (Error $error) {
  103059. throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
  103060. }
  103061. // @codeCoverageIgnoreEnd
  103062. }
  103063. /**
  103064. * @psalm-param non-negative-int $linesOfCode
  103065. *
  103066. * @param Node[] $nodes
  103067. *
  103068. * @throws RuntimeException
  103069. */
  103070. public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode
  103071. {
  103072. $traverser = new NodeTraverser();
  103073. $visitor = new LineCountingVisitor($linesOfCode);
  103074. $traverser->addVisitor($visitor);
  103075. try {
  103076. /* @noinspection UnusedFunctionResultInspection */
  103077. $traverser->traverse($nodes);
  103078. // @codeCoverageIgnoreStart
  103079. } catch (Error $error) {
  103080. throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
  103081. }
  103082. // @codeCoverageIgnoreEnd
  103083. return $visitor->result();
  103084. }
  103085. }
  103086. <?php
  103087. declare (strict_types=1);
  103088. /*
  103089. * This file is part of sebastian/lines-of-code.
  103090. *
  103091. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103092. *
  103093. * For the full copyright and license information, please view the LICENSE
  103094. * file that was distributed with this source code.
  103095. */
  103096. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103097. use Throwable;
  103098. interface Exception extends Throwable
  103099. {
  103100. }
  103101. <?php
  103102. declare (strict_types=1);
  103103. /*
  103104. * This file is part of sebastian/lines-of-code.
  103105. *
  103106. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103107. *
  103108. * For the full copyright and license information, please view the LICENSE
  103109. * file that was distributed with this source code.
  103110. */
  103111. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103112. use LogicException;
  103113. final class IllogicalValuesException extends LogicException implements Exception
  103114. {
  103115. }
  103116. <?php
  103117. declare (strict_types=1);
  103118. /*
  103119. * This file is part of sebastian/lines-of-code.
  103120. *
  103121. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103122. *
  103123. * For the full copyright and license information, please view the LICENSE
  103124. * file that was distributed with this source code.
  103125. */
  103126. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103127. use InvalidArgumentException;
  103128. final class NegativeValueException extends InvalidArgumentException implements Exception
  103129. {
  103130. }
  103131. <?php
  103132. declare (strict_types=1);
  103133. /*
  103134. * This file is part of sebastian/lines-of-code.
  103135. *
  103136. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103137. *
  103138. * For the full copyright and license information, please view the LICENSE
  103139. * file that was distributed with this source code.
  103140. */
  103141. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103142. final class RuntimeException extends \RuntimeException implements Exception
  103143. {
  103144. }
  103145. BSD 3-Clause License
  103146. Copyright (c) 2020-2023, Sebastian Bergmann
  103147. All rights reserved.
  103148. Redistribution and use in source and binary forms, with or without
  103149. modification, are permitted provided that the following conditions are met:
  103150. 1. Redistributions of source code must retain the above copyright notice, this
  103151. list of conditions and the following disclaimer.
  103152. 2. Redistributions in binary form must reproduce the above copyright notice,
  103153. this list of conditions and the following disclaimer in the documentation
  103154. and/or other materials provided with the distribution.
  103155. 3. Neither the name of the copyright holder nor the names of its
  103156. contributors may be used to endorse or promote products derived from
  103157. this software without specific prior written permission.
  103158. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  103159. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  103160. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  103161. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  103162. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  103163. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  103164. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  103165. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  103166. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  103167. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  103168. <?php
  103169. declare (strict_types=1);
  103170. /*
  103171. * This file is part of sebastian/lines-of-code.
  103172. *
  103173. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103174. *
  103175. * For the full copyright and license information, please view the LICENSE
  103176. * file that was distributed with this source code.
  103177. */
  103178. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103179. use function array_merge;
  103180. use function array_unique;
  103181. use function assert;
  103182. use function count;
  103183. use PHPUnitPHAR\PhpParser\Comment;
  103184. use PHPUnitPHAR\PhpParser\Node;
  103185. use PHPUnitPHAR\PhpParser\Node\Expr;
  103186. use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
  103187. final class LineCountingVisitor extends NodeVisitorAbstract
  103188. {
  103189. /**
  103190. * @psalm-var non-negative-int
  103191. */
  103192. private readonly int $linesOfCode;
  103193. /**
  103194. * @var Comment[]
  103195. */
  103196. private array $comments = [];
  103197. /**
  103198. * @var int[]
  103199. */
  103200. private array $linesWithStatements = [];
  103201. /**
  103202. * @psalm-param non-negative-int $linesOfCode
  103203. */
  103204. public function __construct(int $linesOfCode)
  103205. {
  103206. $this->linesOfCode = $linesOfCode;
  103207. }
  103208. public function enterNode(Node $node): void
  103209. {
  103210. $this->comments = array_merge($this->comments, $node->getComments());
  103211. if (!$node instanceof Expr) {
  103212. return;
  103213. }
  103214. $this->linesWithStatements[] = $node->getStartLine();
  103215. }
  103216. public function result(): LinesOfCode
  103217. {
  103218. $commentLinesOfCode = 0;
  103219. foreach ($this->comments() as $comment) {
  103220. $commentLinesOfCode += $comment->getEndLine() - $comment->getStartLine() + 1;
  103221. }
  103222. $nonCommentLinesOfCode = $this->linesOfCode - $commentLinesOfCode;
  103223. $logicalLinesOfCode = count(array_unique($this->linesWithStatements));
  103224. assert($commentLinesOfCode >= 0);
  103225. assert($nonCommentLinesOfCode >= 0);
  103226. assert($logicalLinesOfCode >= 0);
  103227. return new LinesOfCode($this->linesOfCode, $commentLinesOfCode, $nonCommentLinesOfCode, $logicalLinesOfCode);
  103228. }
  103229. /**
  103230. * @return Comment[]
  103231. */
  103232. private function comments(): array
  103233. {
  103234. $comments = [];
  103235. foreach ($this->comments as $comment) {
  103236. $comments[$comment->getStartLine() . '_' . $comment->getStartTokenPos() . '_' . $comment->getEndLine() . '_' . $comment->getEndTokenPos()] = $comment;
  103237. }
  103238. return $comments;
  103239. }
  103240. }
  103241. <?php
  103242. declare (strict_types=1);
  103243. /*
  103244. * This file is part of sebastian/lines-of-code.
  103245. *
  103246. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103247. *
  103248. * For the full copyright and license information, please view the LICENSE
  103249. * file that was distributed with this source code.
  103250. */
  103251. namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
  103252. /**
  103253. * @psalm-immutable
  103254. */
  103255. final class LinesOfCode
  103256. {
  103257. /**
  103258. * @psalm-var non-negative-int
  103259. */
  103260. private readonly int $linesOfCode;
  103261. /**
  103262. * @psalm-var non-negative-int
  103263. */
  103264. private readonly int $commentLinesOfCode;
  103265. /**
  103266. * @psalm-var non-negative-int
  103267. */
  103268. private readonly int $nonCommentLinesOfCode;
  103269. /**
  103270. * @psalm-var non-negative-int
  103271. */
  103272. private readonly int $logicalLinesOfCode;
  103273. /**
  103274. * @psalm-param non-negative-int $linesOfCode
  103275. * @psalm-param non-negative-int $commentLinesOfCode
  103276. * @psalm-param non-negative-int $nonCommentLinesOfCode
  103277. * @psalm-param non-negative-int $logicalLinesOfCode
  103278. *
  103279. * @throws IllogicalValuesException
  103280. * @throws NegativeValueException
  103281. */
  103282. public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode)
  103283. {
  103284. /** @psalm-suppress DocblockTypeContradiction */
  103285. if ($linesOfCode < 0) {
  103286. throw new NegativeValueException('$linesOfCode must not be negative');
  103287. }
  103288. /** @psalm-suppress DocblockTypeContradiction */
  103289. if ($commentLinesOfCode < 0) {
  103290. throw new NegativeValueException('$commentLinesOfCode must not be negative');
  103291. }
  103292. /** @psalm-suppress DocblockTypeContradiction */
  103293. if ($nonCommentLinesOfCode < 0) {
  103294. throw new NegativeValueException('$nonCommentLinesOfCode must not be negative');
  103295. }
  103296. /** @psalm-suppress DocblockTypeContradiction */
  103297. if ($logicalLinesOfCode < 0) {
  103298. throw new NegativeValueException('$logicalLinesOfCode must not be negative');
  103299. }
  103300. if ($linesOfCode - $commentLinesOfCode !== $nonCommentLinesOfCode) {
  103301. throw new IllogicalValuesException('$linesOfCode !== $commentLinesOfCode + $nonCommentLinesOfCode');
  103302. }
  103303. $this->linesOfCode = $linesOfCode;
  103304. $this->commentLinesOfCode = $commentLinesOfCode;
  103305. $this->nonCommentLinesOfCode = $nonCommentLinesOfCode;
  103306. $this->logicalLinesOfCode = $logicalLinesOfCode;
  103307. }
  103308. /**
  103309. * @psalm-return non-negative-int
  103310. */
  103311. public function linesOfCode(): int
  103312. {
  103313. return $this->linesOfCode;
  103314. }
  103315. /**
  103316. * @psalm-return non-negative-int
  103317. */
  103318. public function commentLinesOfCode(): int
  103319. {
  103320. return $this->commentLinesOfCode;
  103321. }
  103322. /**
  103323. * @psalm-return non-negative-int
  103324. */
  103325. public function nonCommentLinesOfCode(): int
  103326. {
  103327. return $this->nonCommentLinesOfCode;
  103328. }
  103329. /**
  103330. * @psalm-return non-negative-int
  103331. */
  103332. public function logicalLinesOfCode(): int
  103333. {
  103334. return $this->logicalLinesOfCode;
  103335. }
  103336. public function plus(self $other): self
  103337. {
  103338. return new self($this->linesOfCode() + $other->linesOfCode(), $this->commentLinesOfCode() + $other->commentLinesOfCode(), $this->nonCommentLinesOfCode() + $other->nonCommentLinesOfCode(), $this->logicalLinesOfCode() + $other->logicalLinesOfCode());
  103339. }
  103340. }
  103341. <?php
  103342. declare (strict_types=1);
  103343. /*
  103344. * This file is part of sebastian/object-enumerator.
  103345. *
  103346. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103347. *
  103348. * For the full copyright and license information, please view the LICENSE
  103349. * file that was distributed with this source code.
  103350. */
  103351. namespace PHPUnitPHAR\SebastianBergmann\ObjectEnumerator;
  103352. use function array_merge;
  103353. use function is_array;
  103354. use function is_object;
  103355. use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
  103356. use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
  103357. final class Enumerator
  103358. {
  103359. /**
  103360. * @psalm-return list<object>
  103361. */
  103362. public function enumerate(array|object $variable, Context $processed = new Context()): array
  103363. {
  103364. $objects = [];
  103365. if ($processed->contains($variable)) {
  103366. return $objects;
  103367. }
  103368. $array = $variable;
  103369. /* @noinspection UnusedFunctionResultInspection */
  103370. $processed->add($variable);
  103371. if (is_array($variable)) {
  103372. foreach ($array as $element) {
  103373. if (!is_array($element) && !is_object($element)) {
  103374. continue;
  103375. }
  103376. /** @noinspection SlowArrayOperationsInLoopInspection */
  103377. $objects = array_merge($objects, $this->enumerate($element, $processed));
  103378. }
  103379. return $objects;
  103380. }
  103381. $objects[] = $variable;
  103382. foreach ((new ObjectReflector())->getProperties($variable) as $value) {
  103383. if (!is_array($value) && !is_object($value)) {
  103384. continue;
  103385. }
  103386. /** @noinspection SlowArrayOperationsInLoopInspection */
  103387. $objects = array_merge($objects, $this->enumerate($value, $processed));
  103388. }
  103389. return $objects;
  103390. }
  103391. }
  103392. <?php
  103393. declare (strict_types=1);
  103394. /*
  103395. * This file is part of sebastian/object-reflector.
  103396. *
  103397. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103398. *
  103399. * For the full copyright and license information, please view the LICENSE
  103400. * file that was distributed with this source code.
  103401. */
  103402. namespace PHPUnitPHAR\SebastianBergmann\ObjectReflector;
  103403. use function count;
  103404. use function explode;
  103405. final class ObjectReflector
  103406. {
  103407. /**
  103408. * @psalm-return array<string,mixed>
  103409. */
  103410. public function getProperties(object $object): array
  103411. {
  103412. $properties = [];
  103413. $className = $object::class;
  103414. foreach ((array) $object as $name => $value) {
  103415. $name = explode("\x00", (string) $name);
  103416. if (count($name) === 1) {
  103417. $name = $name[0];
  103418. } elseif ($name[1] !== $className) {
  103419. $name = $name[1] . '::' . $name[2];
  103420. } else {
  103421. $name = $name[2];
  103422. }
  103423. $properties[$name] = $value;
  103424. }
  103425. return $properties;
  103426. }
  103427. }
  103428. <?php
  103429. declare (strict_types=1);
  103430. /*
  103431. * This file is part of sebastian/recursion-context.
  103432. *
  103433. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103434. *
  103435. * For the full copyright and license information, please view the LICENSE
  103436. * file that was distributed with this source code.
  103437. */
  103438. namespace PHPUnitPHAR\SebastianBergmann\RecursionContext;
  103439. use const PHP_INT_MAX;
  103440. use const PHP_INT_MIN;
  103441. use function array_key_exists;
  103442. use function array_pop;
  103443. use function array_slice;
  103444. use function count;
  103445. use function is_array;
  103446. use function random_int;
  103447. use function spl_object_hash;
  103448. use SplObjectStorage;
  103449. final class Context
  103450. {
  103451. private array $arrays = [];
  103452. private SplObjectStorage $objects;
  103453. public function __construct()
  103454. {
  103455. $this->objects = new SplObjectStorage();
  103456. }
  103457. /**
  103458. * @codeCoverageIgnore
  103459. */
  103460. public function __destruct()
  103461. {
  103462. foreach ($this->arrays as &$array) {
  103463. if (is_array($array)) {
  103464. array_pop($array);
  103465. array_pop($array);
  103466. }
  103467. }
  103468. }
  103469. /**
  103470. * @psalm-template T
  103471. *
  103472. * @psalm-param T $value
  103473. *
  103474. * @param-out T $value
  103475. */
  103476. public function add(object|array &$value): int|string|false
  103477. {
  103478. if (is_array($value)) {
  103479. return $this->addArray($value);
  103480. }
  103481. return $this->addObject($value);
  103482. }
  103483. /**
  103484. * @psalm-template T
  103485. *
  103486. * @psalm-param T $value
  103487. *
  103488. * @param-out T $value
  103489. */
  103490. public function contains(object|array &$value): int|string|false
  103491. {
  103492. if (is_array($value)) {
  103493. return $this->containsArray($value);
  103494. }
  103495. return $this->containsObject($value);
  103496. }
  103497. private function addArray(array &$array): int
  103498. {
  103499. $key = $this->containsArray($array);
  103500. if ($key !== \false) {
  103501. return $key;
  103502. }
  103503. $key = count($this->arrays);
  103504. $this->arrays[] =& $array;
  103505. if (!array_key_exists(PHP_INT_MAX, $array) && !array_key_exists(PHP_INT_MAX - 1, $array)) {
  103506. $array[] = $key;
  103507. $array[] = $this->objects;
  103508. } else {
  103509. /* Cover the improbable case, too.
  103510. *
  103511. * Note that array_slice() (used in containsArray()) will return the
  103512. * last two values added, *not necessarily* the highest integer keys
  103513. * in the array. Therefore, the order of these writes to $array is
  103514. * important, but the actual keys used is not. */
  103515. do {
  103516. /** @noinspection PhpUnhandledExceptionInspection */
  103517. $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
  103518. } while (array_key_exists($key, $array));
  103519. $array[$key] = $key;
  103520. do {
  103521. /** @noinspection PhpUnhandledExceptionInspection */
  103522. $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
  103523. } while (array_key_exists($key, $array));
  103524. $array[$key] = $this->objects;
  103525. }
  103526. return $key;
  103527. }
  103528. private function addObject(object $object): string
  103529. {
  103530. if (!$this->objects->contains($object)) {
  103531. $this->objects->attach($object);
  103532. }
  103533. return spl_object_hash($object);
  103534. }
  103535. private function containsArray(array $array): int|false
  103536. {
  103537. $end = array_slice($array, -2);
  103538. return isset($end[1]) && $end[1] === $this->objects ? $end[0] : \false;
  103539. }
  103540. private function containsObject(object $value): string|false
  103541. {
  103542. if ($this->objects->contains($value)) {
  103543. return spl_object_hash($value);
  103544. }
  103545. return \false;
  103546. }
  103547. }
  103548. BSD 3-Clause License
  103549. Copyright (c) 2002-2023, Sebastian Bergmann
  103550. All rights reserved.
  103551. Redistribution and use in source and binary forms, with or without
  103552. modification, are permitted provided that the following conditions are met:
  103553. 1. Redistributions of source code must retain the above copyright notice, this
  103554. list of conditions and the following disclaimer.
  103555. 2. Redistributions in binary form must reproduce the above copyright notice,
  103556. this list of conditions and the following disclaimer in the documentation
  103557. and/or other materials provided with the distribution.
  103558. 3. Neither the name of the copyright holder nor the names of its
  103559. contributors may be used to endorse or promote products derived from
  103560. this software without specific prior written permission.
  103561. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  103562. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  103563. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  103564. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  103565. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  103566. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  103567. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  103568. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  103569. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  103570. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  103571. BSD 3-Clause License
  103572. Copyright (c) 2019-2023, Sebastian Bergmann
  103573. All rights reserved.
  103574. Redistribution and use in source and binary forms, with or without
  103575. modification, are permitted provided that the following conditions are met:
  103576. 1. Redistributions of source code must retain the above copyright notice, this
  103577. list of conditions and the following disclaimer.
  103578. 2. Redistributions in binary form must reproduce the above copyright notice,
  103579. this list of conditions and the following disclaimer in the documentation
  103580. and/or other materials provided with the distribution.
  103581. 3. Neither the name of the copyright holder nor the names of its
  103582. contributors may be used to endorse or promote products derived from
  103583. this software without specific prior written permission.
  103584. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  103585. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  103586. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  103587. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  103588. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  103589. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  103590. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  103591. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  103592. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  103593. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  103594. <?php
  103595. declare (strict_types=1);
  103596. /*
  103597. * This file is part of sebastian/type.
  103598. *
  103599. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103600. *
  103601. * For the full copyright and license information, please view the LICENSE
  103602. * file that was distributed with this source code.
  103603. */
  103604. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103605. final class Parameter
  103606. {
  103607. /**
  103608. * @psalm-var non-empty-string
  103609. */
  103610. private string $name;
  103611. private Type $type;
  103612. /**
  103613. * @psalm-param non-empty-string $name
  103614. */
  103615. public function __construct(string $name, Type $type)
  103616. {
  103617. $this->name = $name;
  103618. $this->type = $type;
  103619. }
  103620. public function name(): string
  103621. {
  103622. return $this->name;
  103623. }
  103624. public function type(): Type
  103625. {
  103626. return $this->type;
  103627. }
  103628. }
  103629. <?php
  103630. declare (strict_types=1);
  103631. /*
  103632. * This file is part of sebastian/type.
  103633. *
  103634. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103635. *
  103636. * For the full copyright and license information, please view the LICENSE
  103637. * file that was distributed with this source code.
  103638. */
  103639. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103640. use function assert;
  103641. use ReflectionFunction;
  103642. use ReflectionIntersectionType;
  103643. use ReflectionMethod;
  103644. use ReflectionNamedType;
  103645. use ReflectionType;
  103646. use ReflectionUnionType;
  103647. final class ReflectionMapper
  103648. {
  103649. /**
  103650. * @psalm-return list<Parameter>
  103651. */
  103652. public function fromParameterTypes(ReflectionFunction|ReflectionMethod $functionOrMethod): array
  103653. {
  103654. $parameters = [];
  103655. foreach ($functionOrMethod->getParameters() as $parameter) {
  103656. $name = $parameter->getName();
  103657. assert($name !== '');
  103658. if (!$parameter->hasType()) {
  103659. $parameters[] = new Parameter($name, new UnknownType());
  103660. continue;
  103661. }
  103662. $type = $parameter->getType();
  103663. if ($type instanceof ReflectionNamedType) {
  103664. $parameters[] = new Parameter($name, $this->mapNamedType($type, $functionOrMethod));
  103665. continue;
  103666. }
  103667. if ($type instanceof ReflectionUnionType) {
  103668. $parameters[] = new Parameter($name, $this->mapUnionType($type, $functionOrMethod));
  103669. continue;
  103670. }
  103671. if ($type instanceof ReflectionIntersectionType) {
  103672. $parameters[] = new Parameter($name, $this->mapIntersectionType($type, $functionOrMethod));
  103673. }
  103674. }
  103675. return $parameters;
  103676. }
  103677. public function fromReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): Type
  103678. {
  103679. if (!$this->hasReturnType($functionOrMethod)) {
  103680. return new UnknownType();
  103681. }
  103682. $returnType = $this->returnType($functionOrMethod);
  103683. assert($returnType instanceof ReflectionNamedType || $returnType instanceof ReflectionUnionType || $returnType instanceof ReflectionIntersectionType);
  103684. if ($returnType instanceof ReflectionNamedType) {
  103685. return $this->mapNamedType($returnType, $functionOrMethod);
  103686. }
  103687. if ($returnType instanceof ReflectionUnionType) {
  103688. return $this->mapUnionType($returnType, $functionOrMethod);
  103689. }
  103690. if ($returnType instanceof ReflectionIntersectionType) {
  103691. return $this->mapIntersectionType($returnType, $functionOrMethod);
  103692. }
  103693. }
  103694. private function mapNamedType(ReflectionNamedType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
  103695. {
  103696. if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'self') {
  103697. return ObjectType::fromName($functionOrMethod->getDeclaringClass()->getName(), $type->allowsNull());
  103698. }
  103699. if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'static') {
  103700. return new StaticType(TypeName::fromReflection($functionOrMethod->getDeclaringClass()), $type->allowsNull());
  103701. }
  103702. if ($type->getName() === 'mixed') {
  103703. return new MixedType();
  103704. }
  103705. if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'parent') {
  103706. return ObjectType::fromName($functionOrMethod->getDeclaringClass()->getParentClass()->getName(), $type->allowsNull());
  103707. }
  103708. return Type::fromName($type->getName(), $type->allowsNull());
  103709. }
  103710. private function mapUnionType(ReflectionUnionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
  103711. {
  103712. $types = [];
  103713. foreach ($type->getTypes() as $_type) {
  103714. assert($_type instanceof ReflectionNamedType || $_type instanceof ReflectionIntersectionType);
  103715. if ($_type instanceof ReflectionNamedType) {
  103716. $types[] = $this->mapNamedType($_type, $functionOrMethod);
  103717. continue;
  103718. }
  103719. $types[] = $this->mapIntersectionType($_type, $functionOrMethod);
  103720. }
  103721. return new UnionType(...$types);
  103722. }
  103723. private function mapIntersectionType(ReflectionIntersectionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
  103724. {
  103725. $types = [];
  103726. foreach ($type->getTypes() as $_type) {
  103727. assert($_type instanceof ReflectionNamedType);
  103728. $types[] = $this->mapNamedType($_type, $functionOrMethod);
  103729. }
  103730. return new IntersectionType(...$types);
  103731. }
  103732. private function hasReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): bool
  103733. {
  103734. if ($functionOrMethod->hasReturnType()) {
  103735. return \true;
  103736. }
  103737. return $functionOrMethod->hasTentativeReturnType();
  103738. }
  103739. private function returnType(ReflectionFunction|ReflectionMethod $functionOrMethod): ?ReflectionType
  103740. {
  103741. if ($functionOrMethod->hasReturnType()) {
  103742. return $functionOrMethod->getReturnType();
  103743. }
  103744. return $functionOrMethod->getTentativeReturnType();
  103745. }
  103746. }
  103747. <?php
  103748. declare (strict_types=1);
  103749. /*
  103750. * This file is part of sebastian/type.
  103751. *
  103752. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103753. *
  103754. * For the full copyright and license information, please view the LICENSE
  103755. * file that was distributed with this source code.
  103756. */
  103757. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103758. use function array_pop;
  103759. use function explode;
  103760. use function implode;
  103761. use function substr;
  103762. use ReflectionClass;
  103763. final class TypeName
  103764. {
  103765. private ?string $namespaceName;
  103766. private string $simpleName;
  103767. public static function fromQualifiedName(string $fullClassName): self
  103768. {
  103769. if ($fullClassName[0] === '\\') {
  103770. $fullClassName = substr($fullClassName, 1);
  103771. }
  103772. $classNameParts = explode('\\', $fullClassName);
  103773. $simpleName = array_pop($classNameParts);
  103774. $namespaceName = implode('\\', $classNameParts);
  103775. return new self($namespaceName, $simpleName);
  103776. }
  103777. public static function fromReflection(ReflectionClass $type): self
  103778. {
  103779. return new self($type->getNamespaceName(), $type->getShortName());
  103780. }
  103781. public function __construct(?string $namespaceName, string $simpleName)
  103782. {
  103783. if ($namespaceName === '') {
  103784. $namespaceName = null;
  103785. }
  103786. $this->namespaceName = $namespaceName;
  103787. $this->simpleName = $simpleName;
  103788. }
  103789. public function namespaceName(): ?string
  103790. {
  103791. return $this->namespaceName;
  103792. }
  103793. public function simpleName(): string
  103794. {
  103795. return $this->simpleName;
  103796. }
  103797. public function qualifiedName(): string
  103798. {
  103799. return $this->namespaceName === null ? $this->simpleName : $this->namespaceName . '\\' . $this->simpleName;
  103800. }
  103801. public function isNamespaced(): bool
  103802. {
  103803. return $this->namespaceName !== null;
  103804. }
  103805. }
  103806. <?php
  103807. declare (strict_types=1);
  103808. /*
  103809. * This file is part of sebastian/type.
  103810. *
  103811. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103812. *
  103813. * For the full copyright and license information, please view the LICENSE
  103814. * file that was distributed with this source code.
  103815. */
  103816. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103817. use Throwable;
  103818. interface Exception extends Throwable
  103819. {
  103820. }
  103821. <?php
  103822. declare (strict_types=1);
  103823. /*
  103824. * This file is part of sebastian/type.
  103825. *
  103826. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103827. *
  103828. * For the full copyright and license information, please view the LICENSE
  103829. * file that was distributed with this source code.
  103830. */
  103831. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103832. final class RuntimeException extends \RuntimeException implements Exception
  103833. {
  103834. }
  103835. <?php
  103836. declare (strict_types=1);
  103837. /*
  103838. * This file is part of sebastian/type.
  103839. *
  103840. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103841. *
  103842. * For the full copyright and license information, please view the LICENSE
  103843. * file that was distributed with this source code.
  103844. */
  103845. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103846. use function assert;
  103847. use function class_exists;
  103848. use function count;
  103849. use function explode;
  103850. use function function_exists;
  103851. use function is_array;
  103852. use function is_object;
  103853. use function is_string;
  103854. use function str_contains;
  103855. use Closure;
  103856. use ReflectionClass;
  103857. use ReflectionObject;
  103858. final class CallableType extends Type
  103859. {
  103860. private bool $allowsNull;
  103861. public function __construct(bool $nullable)
  103862. {
  103863. $this->allowsNull = $nullable;
  103864. }
  103865. public function isAssignable(Type $other): bool
  103866. {
  103867. if ($this->allowsNull && $other instanceof NullType) {
  103868. return \true;
  103869. }
  103870. if ($other instanceof self) {
  103871. return \true;
  103872. }
  103873. if ($other instanceof ObjectType) {
  103874. if ($this->isClosure($other)) {
  103875. return \true;
  103876. }
  103877. if ($this->hasInvokeMethod($other)) {
  103878. return \true;
  103879. }
  103880. }
  103881. if ($other instanceof SimpleType) {
  103882. if ($this->isFunction($other)) {
  103883. return \true;
  103884. }
  103885. if ($this->isClassCallback($other)) {
  103886. return \true;
  103887. }
  103888. if ($this->isObjectCallback($other)) {
  103889. return \true;
  103890. }
  103891. }
  103892. return \false;
  103893. }
  103894. public function name(): string
  103895. {
  103896. return 'callable';
  103897. }
  103898. public function allowsNull(): bool
  103899. {
  103900. return $this->allowsNull;
  103901. }
  103902. /**
  103903. * @psalm-assert-if-true CallableType $this
  103904. */
  103905. public function isCallable(): bool
  103906. {
  103907. return \true;
  103908. }
  103909. private function isClosure(ObjectType $type): bool
  103910. {
  103911. return $type->className()->qualifiedName() === Closure::class;
  103912. }
  103913. private function hasInvokeMethod(ObjectType $type): bool
  103914. {
  103915. $className = $type->className()->qualifiedName();
  103916. assert(class_exists($className));
  103917. return (new ReflectionClass($className))->hasMethod('__invoke');
  103918. }
  103919. private function isFunction(SimpleType $type): bool
  103920. {
  103921. if (!is_string($type->value())) {
  103922. return \false;
  103923. }
  103924. return function_exists($type->value());
  103925. }
  103926. private function isObjectCallback(SimpleType $type): bool
  103927. {
  103928. if (!is_array($type->value())) {
  103929. return \false;
  103930. }
  103931. if (count($type->value()) !== 2) {
  103932. return \false;
  103933. }
  103934. if (!isset($type->value()[0], $type->value()[1])) {
  103935. return \false;
  103936. }
  103937. if (!is_object($type->value()[0]) || !is_string($type->value()[1])) {
  103938. return \false;
  103939. }
  103940. [$object, $methodName] = $type->value();
  103941. return (new ReflectionObject($object))->hasMethod($methodName);
  103942. }
  103943. private function isClassCallback(SimpleType $type): bool
  103944. {
  103945. if (!is_string($type->value()) && !is_array($type->value())) {
  103946. return \false;
  103947. }
  103948. if (is_string($type->value())) {
  103949. if (!str_contains($type->value(), '::')) {
  103950. return \false;
  103951. }
  103952. [$className, $methodName] = explode('::', $type->value());
  103953. }
  103954. if (is_array($type->value())) {
  103955. if (count($type->value()) !== 2) {
  103956. return \false;
  103957. }
  103958. if (!isset($type->value()[0], $type->value()[1])) {
  103959. return \false;
  103960. }
  103961. if (!is_string($type->value()[0]) || !is_string($type->value()[1])) {
  103962. return \false;
  103963. }
  103964. [$className, $methodName] = $type->value();
  103965. }
  103966. assert(isset($className) && is_string($className));
  103967. assert(isset($methodName) && is_string($methodName));
  103968. if (!class_exists($className)) {
  103969. return \false;
  103970. }
  103971. $class = new ReflectionClass($className);
  103972. if (!$class->hasMethod($methodName)) {
  103973. return \false;
  103974. }
  103975. $method = $class->getMethod($methodName);
  103976. return $method->isPublic() && $method->isStatic();
  103977. }
  103978. }
  103979. <?php
  103980. declare (strict_types=1);
  103981. /*
  103982. * This file is part of sebastian/type.
  103983. *
  103984. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  103985. *
  103986. * For the full copyright and license information, please view the LICENSE
  103987. * file that was distributed with this source code.
  103988. */
  103989. namespace PHPUnitPHAR\SebastianBergmann\Type;
  103990. final class FalseType extends Type
  103991. {
  103992. public function isAssignable(Type $other): bool
  103993. {
  103994. if ($other instanceof self) {
  103995. return \true;
  103996. }
  103997. return $other instanceof SimpleType && $other->name() === 'bool' && $other->value() === \false;
  103998. }
  103999. public function name(): string
  104000. {
  104001. return 'false';
  104002. }
  104003. public function allowsNull(): bool
  104004. {
  104005. return \false;
  104006. }
  104007. /**
  104008. * @psalm-assert-if-true FalseType $this
  104009. */
  104010. public function isFalse(): bool
  104011. {
  104012. return \true;
  104013. }
  104014. }
  104015. <?php
  104016. declare (strict_types=1);
  104017. /*
  104018. * This file is part of sebastian/type.
  104019. *
  104020. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104021. *
  104022. * For the full copyright and license information, please view the LICENSE
  104023. * file that was distributed with this source code.
  104024. */
  104025. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104026. final class GenericObjectType extends Type
  104027. {
  104028. private bool $allowsNull;
  104029. public function __construct(bool $nullable)
  104030. {
  104031. $this->allowsNull = $nullable;
  104032. }
  104033. public function isAssignable(Type $other): bool
  104034. {
  104035. if ($this->allowsNull && $other instanceof NullType) {
  104036. return \true;
  104037. }
  104038. if (!$other instanceof ObjectType) {
  104039. return \false;
  104040. }
  104041. return \true;
  104042. }
  104043. public function name(): string
  104044. {
  104045. return 'object';
  104046. }
  104047. public function allowsNull(): bool
  104048. {
  104049. return $this->allowsNull;
  104050. }
  104051. /**
  104052. * @psalm-assert-if-true GenericObjectType $this
  104053. */
  104054. public function isGenericObject(): bool
  104055. {
  104056. return \true;
  104057. }
  104058. }
  104059. <?php
  104060. declare (strict_types=1);
  104061. /*
  104062. * This file is part of sebastian/type.
  104063. *
  104064. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104065. *
  104066. * For the full copyright and license information, please view the LICENSE
  104067. * file that was distributed with this source code.
  104068. */
  104069. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104070. use function assert;
  104071. use function count;
  104072. use function implode;
  104073. use function in_array;
  104074. use function sort;
  104075. final class IntersectionType extends Type
  104076. {
  104077. /**
  104078. * @psalm-var non-empty-list<Type>
  104079. */
  104080. private array $types;
  104081. /**
  104082. * @throws RuntimeException
  104083. */
  104084. public function __construct(Type ...$types)
  104085. {
  104086. $this->ensureMinimumOfTwoTypes(...$types);
  104087. $this->ensureOnlyValidTypes(...$types);
  104088. $this->ensureNoDuplicateTypes(...$types);
  104089. $this->types = $types;
  104090. }
  104091. public function isAssignable(Type $other): bool
  104092. {
  104093. return $other->isObject();
  104094. }
  104095. public function asString(): string
  104096. {
  104097. return $this->name();
  104098. }
  104099. public function name(): string
  104100. {
  104101. $types = [];
  104102. foreach ($this->types as $type) {
  104103. $types[] = $type->name();
  104104. }
  104105. sort($types);
  104106. return implode('&', $types);
  104107. }
  104108. public function allowsNull(): bool
  104109. {
  104110. return \false;
  104111. }
  104112. /**
  104113. * @psalm-assert-if-true IntersectionType $this
  104114. */
  104115. public function isIntersection(): bool
  104116. {
  104117. return \true;
  104118. }
  104119. /**
  104120. * @psalm-return non-empty-list<Type>
  104121. */
  104122. public function types(): array
  104123. {
  104124. return $this->types;
  104125. }
  104126. /**
  104127. * @throws RuntimeException
  104128. */
  104129. private function ensureMinimumOfTwoTypes(Type ...$types): void
  104130. {
  104131. if (count($types) < 2) {
  104132. throw new RuntimeException('An intersection type must be composed of at least two types');
  104133. }
  104134. }
  104135. /**
  104136. * @throws RuntimeException
  104137. */
  104138. private function ensureOnlyValidTypes(Type ...$types): void
  104139. {
  104140. foreach ($types as $type) {
  104141. if (!$type->isObject()) {
  104142. throw new RuntimeException('An intersection type can only be composed of interfaces and classes');
  104143. }
  104144. }
  104145. }
  104146. /**
  104147. * @throws RuntimeException
  104148. */
  104149. private function ensureNoDuplicateTypes(Type ...$types): void
  104150. {
  104151. $names = [];
  104152. foreach ($types as $type) {
  104153. assert($type instanceof ObjectType);
  104154. $classQualifiedName = $type->className()->qualifiedName();
  104155. if (in_array($classQualifiedName, $names, \true)) {
  104156. throw new RuntimeException('An intersection type must not contain duplicate types');
  104157. }
  104158. $names[] = $classQualifiedName;
  104159. }
  104160. }
  104161. }
  104162. <?php
  104163. declare (strict_types=1);
  104164. /*
  104165. * This file is part of sebastian/type.
  104166. *
  104167. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104168. *
  104169. * For the full copyright and license information, please view the LICENSE
  104170. * file that was distributed with this source code.
  104171. */
  104172. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104173. use function assert;
  104174. use function class_exists;
  104175. use function is_iterable;
  104176. use ReflectionClass;
  104177. final class IterableType extends Type
  104178. {
  104179. private bool $allowsNull;
  104180. public function __construct(bool $nullable)
  104181. {
  104182. $this->allowsNull = $nullable;
  104183. }
  104184. /**
  104185. * @throws RuntimeException
  104186. */
  104187. public function isAssignable(Type $other): bool
  104188. {
  104189. if ($this->allowsNull && $other instanceof NullType) {
  104190. return \true;
  104191. }
  104192. if ($other instanceof self) {
  104193. return \true;
  104194. }
  104195. if ($other instanceof SimpleType) {
  104196. return is_iterable($other->value());
  104197. }
  104198. if ($other instanceof ObjectType) {
  104199. $className = $other->className()->qualifiedName();
  104200. assert(class_exists($className));
  104201. return (new ReflectionClass($className))->isIterable();
  104202. }
  104203. return \false;
  104204. }
  104205. public function name(): string
  104206. {
  104207. return 'iterable';
  104208. }
  104209. public function allowsNull(): bool
  104210. {
  104211. return $this->allowsNull;
  104212. }
  104213. /**
  104214. * @psalm-assert-if-true IterableType $this
  104215. */
  104216. public function isIterable(): bool
  104217. {
  104218. return \true;
  104219. }
  104220. }
  104221. <?php
  104222. declare (strict_types=1);
  104223. /*
  104224. * This file is part of sebastian/type.
  104225. *
  104226. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104227. *
  104228. * For the full copyright and license information, please view the LICENSE
  104229. * file that was distributed with this source code.
  104230. */
  104231. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104232. final class MixedType extends Type
  104233. {
  104234. public function isAssignable(Type $other): bool
  104235. {
  104236. return !$other instanceof VoidType;
  104237. }
  104238. public function asString(): string
  104239. {
  104240. return 'mixed';
  104241. }
  104242. public function name(): string
  104243. {
  104244. return 'mixed';
  104245. }
  104246. public function allowsNull(): bool
  104247. {
  104248. return \true;
  104249. }
  104250. /**
  104251. * @psalm-assert-if-true MixedType $this
  104252. */
  104253. public function isMixed(): bool
  104254. {
  104255. return \true;
  104256. }
  104257. }
  104258. <?php
  104259. declare (strict_types=1);
  104260. /*
  104261. * This file is part of sebastian/type.
  104262. *
  104263. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104264. *
  104265. * For the full copyright and license information, please view the LICENSE
  104266. * file that was distributed with this source code.
  104267. */
  104268. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104269. final class NeverType extends Type
  104270. {
  104271. public function isAssignable(Type $other): bool
  104272. {
  104273. return $other instanceof self;
  104274. }
  104275. public function name(): string
  104276. {
  104277. return 'never';
  104278. }
  104279. public function allowsNull(): bool
  104280. {
  104281. return \false;
  104282. }
  104283. /**
  104284. * @psalm-assert-if-true NeverType $this
  104285. */
  104286. public function isNever(): bool
  104287. {
  104288. return \true;
  104289. }
  104290. }
  104291. <?php
  104292. declare (strict_types=1);
  104293. /*
  104294. * This file is part of sebastian/type.
  104295. *
  104296. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104297. *
  104298. * For the full copyright and license information, please view the LICENSE
  104299. * file that was distributed with this source code.
  104300. */
  104301. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104302. final class NullType extends Type
  104303. {
  104304. public function isAssignable(Type $other): bool
  104305. {
  104306. return !$other instanceof VoidType;
  104307. }
  104308. public function name(): string
  104309. {
  104310. return 'null';
  104311. }
  104312. public function asString(): string
  104313. {
  104314. return 'null';
  104315. }
  104316. public function allowsNull(): bool
  104317. {
  104318. return \true;
  104319. }
  104320. /**
  104321. * @psalm-assert-if-true NullType $this
  104322. */
  104323. public function isNull(): bool
  104324. {
  104325. return \true;
  104326. }
  104327. }
  104328. <?php
  104329. declare (strict_types=1);
  104330. /*
  104331. * This file is part of sebastian/type.
  104332. *
  104333. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104334. *
  104335. * For the full copyright and license information, please view the LICENSE
  104336. * file that was distributed with this source code.
  104337. */
  104338. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104339. use function is_subclass_of;
  104340. use function strcasecmp;
  104341. final class ObjectType extends Type
  104342. {
  104343. private TypeName $className;
  104344. private bool $allowsNull;
  104345. public function __construct(TypeName $className, bool $allowsNull)
  104346. {
  104347. $this->className = $className;
  104348. $this->allowsNull = $allowsNull;
  104349. }
  104350. public function isAssignable(Type $other): bool
  104351. {
  104352. if ($this->allowsNull && $other instanceof NullType) {
  104353. return \true;
  104354. }
  104355. if ($other instanceof self) {
  104356. if (0 === strcasecmp($this->className->qualifiedName(), $other->className->qualifiedName())) {
  104357. return \true;
  104358. }
  104359. if (is_subclass_of($other->className->qualifiedName(), $this->className->qualifiedName(), \true)) {
  104360. return \true;
  104361. }
  104362. }
  104363. return \false;
  104364. }
  104365. public function name(): string
  104366. {
  104367. return $this->className->qualifiedName();
  104368. }
  104369. public function allowsNull(): bool
  104370. {
  104371. return $this->allowsNull;
  104372. }
  104373. public function className(): TypeName
  104374. {
  104375. return $this->className;
  104376. }
  104377. /**
  104378. * @psalm-assert-if-true ObjectType $this
  104379. */
  104380. public function isObject(): bool
  104381. {
  104382. return \true;
  104383. }
  104384. }
  104385. <?php
  104386. declare (strict_types=1);
  104387. /*
  104388. * This file is part of sebastian/type.
  104389. *
  104390. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104391. *
  104392. * For the full copyright and license information, please view the LICENSE
  104393. * file that was distributed with this source code.
  104394. */
  104395. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104396. use function strtolower;
  104397. final class SimpleType extends Type
  104398. {
  104399. private string $name;
  104400. private bool $allowsNull;
  104401. private mixed $value;
  104402. public function __construct(string $name, bool $nullable, mixed $value = null)
  104403. {
  104404. $this->name = $this->normalize($name);
  104405. $this->allowsNull = $nullable;
  104406. $this->value = $value;
  104407. }
  104408. public function isAssignable(Type $other): bool
  104409. {
  104410. if ($this->allowsNull && $other instanceof NullType) {
  104411. return \true;
  104412. }
  104413. if ($this->name === 'bool' && $other->name() === 'true') {
  104414. return \true;
  104415. }
  104416. if ($this->name === 'bool' && $other->name() === 'false') {
  104417. return \true;
  104418. }
  104419. if ($other instanceof self) {
  104420. return $this->name === $other->name;
  104421. }
  104422. return \false;
  104423. }
  104424. public function name(): string
  104425. {
  104426. return $this->name;
  104427. }
  104428. public function allowsNull(): bool
  104429. {
  104430. return $this->allowsNull;
  104431. }
  104432. public function value(): mixed
  104433. {
  104434. return $this->value;
  104435. }
  104436. /**
  104437. * @psalm-assert-if-true SimpleType $this
  104438. */
  104439. public function isSimple(): bool
  104440. {
  104441. return \true;
  104442. }
  104443. private function normalize(string $name): string
  104444. {
  104445. $name = strtolower($name);
  104446. return match ($name) {
  104447. 'boolean' => 'bool',
  104448. 'real', 'double' => 'float',
  104449. 'integer' => 'int',
  104450. '[]' => 'array',
  104451. default => $name,
  104452. };
  104453. }
  104454. }
  104455. <?php
  104456. declare (strict_types=1);
  104457. /*
  104458. * This file is part of sebastian/type.
  104459. *
  104460. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104461. *
  104462. * For the full copyright and license information, please view the LICENSE
  104463. * file that was distributed with this source code.
  104464. */
  104465. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104466. use function is_subclass_of;
  104467. use function strcasecmp;
  104468. final class StaticType extends Type
  104469. {
  104470. private TypeName $className;
  104471. private bool $allowsNull;
  104472. public function __construct(TypeName $className, bool $allowsNull)
  104473. {
  104474. $this->className = $className;
  104475. $this->allowsNull = $allowsNull;
  104476. }
  104477. public function isAssignable(Type $other): bool
  104478. {
  104479. if ($this->allowsNull && $other instanceof NullType) {
  104480. return \true;
  104481. }
  104482. if (!$other instanceof ObjectType) {
  104483. return \false;
  104484. }
  104485. if (0 === strcasecmp($this->className->qualifiedName(), $other->className()->qualifiedName())) {
  104486. return \true;
  104487. }
  104488. if (is_subclass_of($other->className()->qualifiedName(), $this->className->qualifiedName(), \true)) {
  104489. return \true;
  104490. }
  104491. return \false;
  104492. }
  104493. public function name(): string
  104494. {
  104495. return 'static';
  104496. }
  104497. public function allowsNull(): bool
  104498. {
  104499. return $this->allowsNull;
  104500. }
  104501. /**
  104502. * @psalm-assert-if-true StaticType $this
  104503. */
  104504. public function isStatic(): bool
  104505. {
  104506. return \true;
  104507. }
  104508. }
  104509. <?php
  104510. declare (strict_types=1);
  104511. /*
  104512. * This file is part of sebastian/type.
  104513. *
  104514. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104515. *
  104516. * For the full copyright and license information, please view the LICENSE
  104517. * file that was distributed with this source code.
  104518. */
  104519. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104520. final class TrueType extends Type
  104521. {
  104522. public function isAssignable(Type $other): bool
  104523. {
  104524. if ($other instanceof self) {
  104525. return \true;
  104526. }
  104527. return $other instanceof SimpleType && $other->name() === 'bool' && $other->value() === \true;
  104528. }
  104529. public function name(): string
  104530. {
  104531. return 'true';
  104532. }
  104533. public function allowsNull(): bool
  104534. {
  104535. return \false;
  104536. }
  104537. /**
  104538. * @psalm-assert-if-true TrueType $this
  104539. */
  104540. public function isTrue(): bool
  104541. {
  104542. return \true;
  104543. }
  104544. }
  104545. <?php
  104546. declare (strict_types=1);
  104547. /*
  104548. * This file is part of sebastian/type.
  104549. *
  104550. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104551. *
  104552. * For the full copyright and license information, please view the LICENSE
  104553. * file that was distributed with this source code.
  104554. */
  104555. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104556. use function gettype;
  104557. use function strtolower;
  104558. abstract class Type
  104559. {
  104560. public static function fromValue(mixed $value, bool $allowsNull): self
  104561. {
  104562. if ($allowsNull === \false) {
  104563. if ($value === \true) {
  104564. return new TrueType();
  104565. }
  104566. if ($value === \false) {
  104567. return new FalseType();
  104568. }
  104569. }
  104570. $typeName = gettype($value);
  104571. if ($typeName === 'object') {
  104572. return new ObjectType(TypeName::fromQualifiedName($value::class), $allowsNull);
  104573. }
  104574. $type = self::fromName($typeName, $allowsNull);
  104575. if ($type instanceof SimpleType) {
  104576. $type = new SimpleType($typeName, $allowsNull, $value);
  104577. }
  104578. return $type;
  104579. }
  104580. public static function fromName(string $typeName, bool $allowsNull): self
  104581. {
  104582. return match (strtolower($typeName)) {
  104583. 'callable' => new CallableType($allowsNull),
  104584. 'true' => new TrueType(),
  104585. 'false' => new FalseType(),
  104586. 'iterable' => new IterableType($allowsNull),
  104587. 'never' => new NeverType(),
  104588. 'null' => new NullType(),
  104589. 'object' => new GenericObjectType($allowsNull),
  104590. 'unknown type' => new UnknownType(),
  104591. 'void' => new VoidType(),
  104592. 'array', 'bool', 'boolean', 'double', 'float', 'int', 'integer', 'real', 'resource', 'resource (closed)', 'string' => new SimpleType($typeName, $allowsNull),
  104593. 'mixed' => new MixedType(),
  104594. default => new ObjectType(TypeName::fromQualifiedName($typeName), $allowsNull),
  104595. };
  104596. }
  104597. public function asString(): string
  104598. {
  104599. return ($this->allowsNull() ? '?' : '') . $this->name();
  104600. }
  104601. /**
  104602. * @psalm-assert-if-true CallableType $this
  104603. */
  104604. public function isCallable(): bool
  104605. {
  104606. return \false;
  104607. }
  104608. /**
  104609. * @psalm-assert-if-true TrueType $this
  104610. */
  104611. public function isTrue(): bool
  104612. {
  104613. return \false;
  104614. }
  104615. /**
  104616. * @psalm-assert-if-true FalseType $this
  104617. */
  104618. public function isFalse(): bool
  104619. {
  104620. return \false;
  104621. }
  104622. /**
  104623. * @psalm-assert-if-true GenericObjectType $this
  104624. */
  104625. public function isGenericObject(): bool
  104626. {
  104627. return \false;
  104628. }
  104629. /**
  104630. * @psalm-assert-if-true IntersectionType $this
  104631. */
  104632. public function isIntersection(): bool
  104633. {
  104634. return \false;
  104635. }
  104636. /**
  104637. * @psalm-assert-if-true IterableType $this
  104638. */
  104639. public function isIterable(): bool
  104640. {
  104641. return \false;
  104642. }
  104643. /**
  104644. * @psalm-assert-if-true MixedType $this
  104645. */
  104646. public function isMixed(): bool
  104647. {
  104648. return \false;
  104649. }
  104650. /**
  104651. * @psalm-assert-if-true NeverType $this
  104652. */
  104653. public function isNever(): bool
  104654. {
  104655. return \false;
  104656. }
  104657. /**
  104658. * @psalm-assert-if-true NullType $this
  104659. */
  104660. public function isNull(): bool
  104661. {
  104662. return \false;
  104663. }
  104664. /**
  104665. * @psalm-assert-if-true ObjectType $this
  104666. */
  104667. public function isObject(): bool
  104668. {
  104669. return \false;
  104670. }
  104671. /**
  104672. * @psalm-assert-if-true SimpleType $this
  104673. */
  104674. public function isSimple(): bool
  104675. {
  104676. return \false;
  104677. }
  104678. /**
  104679. * @psalm-assert-if-true StaticType $this
  104680. */
  104681. public function isStatic(): bool
  104682. {
  104683. return \false;
  104684. }
  104685. /**
  104686. * @psalm-assert-if-true UnionType $this
  104687. */
  104688. public function isUnion(): bool
  104689. {
  104690. return \false;
  104691. }
  104692. /**
  104693. * @psalm-assert-if-true UnknownType $this
  104694. */
  104695. public function isUnknown(): bool
  104696. {
  104697. return \false;
  104698. }
  104699. /**
  104700. * @psalm-assert-if-true VoidType $this
  104701. */
  104702. public function isVoid(): bool
  104703. {
  104704. return \false;
  104705. }
  104706. abstract public function isAssignable(self $other): bool;
  104707. abstract public function name(): string;
  104708. abstract public function allowsNull(): bool;
  104709. }
  104710. <?php
  104711. declare (strict_types=1);
  104712. /*
  104713. * This file is part of sebastian/type.
  104714. *
  104715. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104716. *
  104717. * For the full copyright and license information, please view the LICENSE
  104718. * file that was distributed with this source code.
  104719. */
  104720. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104721. use function count;
  104722. use function implode;
  104723. use function sort;
  104724. final class UnionType extends Type
  104725. {
  104726. /**
  104727. * @psalm-var non-empty-list<Type>
  104728. */
  104729. private array $types;
  104730. /**
  104731. * @throws RuntimeException
  104732. */
  104733. public function __construct(Type ...$types)
  104734. {
  104735. $this->ensureMinimumOfTwoTypes(...$types);
  104736. $this->ensureOnlyValidTypes(...$types);
  104737. $this->types = $types;
  104738. }
  104739. public function isAssignable(Type $other): bool
  104740. {
  104741. foreach ($this->types as $type) {
  104742. if ($type->isAssignable($other)) {
  104743. return \true;
  104744. }
  104745. }
  104746. return \false;
  104747. }
  104748. public function asString(): string
  104749. {
  104750. return $this->name();
  104751. }
  104752. public function name(): string
  104753. {
  104754. $types = [];
  104755. foreach ($this->types as $type) {
  104756. if ($type->isIntersection()) {
  104757. $types[] = '(' . $type->name() . ')';
  104758. continue;
  104759. }
  104760. $types[] = $type->name();
  104761. }
  104762. sort($types);
  104763. return implode('|', $types);
  104764. }
  104765. public function allowsNull(): bool
  104766. {
  104767. foreach ($this->types as $type) {
  104768. if ($type instanceof NullType) {
  104769. return \true;
  104770. }
  104771. }
  104772. return \false;
  104773. }
  104774. /**
  104775. * @psalm-assert-if-true UnionType $this
  104776. */
  104777. public function isUnion(): bool
  104778. {
  104779. return \true;
  104780. }
  104781. public function containsIntersectionTypes(): bool
  104782. {
  104783. foreach ($this->types as $type) {
  104784. if ($type->isIntersection()) {
  104785. return \true;
  104786. }
  104787. }
  104788. return \false;
  104789. }
  104790. /**
  104791. * @psalm-return non-empty-list<Type>
  104792. */
  104793. public function types(): array
  104794. {
  104795. return $this->types;
  104796. }
  104797. /**
  104798. * @throws RuntimeException
  104799. */
  104800. private function ensureMinimumOfTwoTypes(Type ...$types): void
  104801. {
  104802. if (count($types) < 2) {
  104803. throw new RuntimeException('A union type must be composed of at least two types');
  104804. }
  104805. }
  104806. /**
  104807. * @throws RuntimeException
  104808. */
  104809. private function ensureOnlyValidTypes(Type ...$types): void
  104810. {
  104811. foreach ($types as $type) {
  104812. if ($type instanceof UnknownType) {
  104813. throw new RuntimeException('A union type must not be composed of an unknown type');
  104814. }
  104815. if ($type instanceof VoidType) {
  104816. throw new RuntimeException('A union type must not be composed of a void type');
  104817. }
  104818. }
  104819. }
  104820. }
  104821. <?php
  104822. declare (strict_types=1);
  104823. /*
  104824. * This file is part of sebastian/type.
  104825. *
  104826. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104827. *
  104828. * For the full copyright and license information, please view the LICENSE
  104829. * file that was distributed with this source code.
  104830. */
  104831. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104832. final class UnknownType extends Type
  104833. {
  104834. public function isAssignable(Type $other): bool
  104835. {
  104836. return \true;
  104837. }
  104838. public function name(): string
  104839. {
  104840. return 'unknown type';
  104841. }
  104842. public function asString(): string
  104843. {
  104844. return '';
  104845. }
  104846. public function allowsNull(): bool
  104847. {
  104848. return \true;
  104849. }
  104850. /**
  104851. * @psalm-assert-if-true UnknownType $this
  104852. */
  104853. public function isUnknown(): bool
  104854. {
  104855. return \true;
  104856. }
  104857. }
  104858. <?php
  104859. declare (strict_types=1);
  104860. /*
  104861. * This file is part of sebastian/type.
  104862. *
  104863. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104864. *
  104865. * For the full copyright and license information, please view the LICENSE
  104866. * file that was distributed with this source code.
  104867. */
  104868. namespace PHPUnitPHAR\SebastianBergmann\Type;
  104869. final class VoidType extends Type
  104870. {
  104871. public function isAssignable(Type $other): bool
  104872. {
  104873. return $other instanceof self;
  104874. }
  104875. public function name(): string
  104876. {
  104877. return 'void';
  104878. }
  104879. public function allowsNull(): bool
  104880. {
  104881. return \false;
  104882. }
  104883. /**
  104884. * @psalm-assert-if-true VoidType $this
  104885. */
  104886. public function isVoid(): bool
  104887. {
  104888. return \true;
  104889. }
  104890. }
  104891. BSD 3-Clause License
  104892. Copyright (c) 2013-2023, Sebastian Bergmann
  104893. All rights reserved.
  104894. Redistribution and use in source and binary forms, with or without
  104895. modification, are permitted provided that the following conditions are met:
  104896. 1. Redistributions of source code must retain the above copyright notice, this
  104897. list of conditions and the following disclaimer.
  104898. 2. Redistributions in binary form must reproduce the above copyright notice,
  104899. this list of conditions and the following disclaimer in the documentation
  104900. and/or other materials provided with the distribution.
  104901. 3. Neither the name of the copyright holder nor the names of its
  104902. contributors may be used to endorse or promote products derived from
  104903. this software without specific prior written permission.
  104904. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  104905. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  104906. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  104907. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  104908. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  104909. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  104910. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  104911. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  104912. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  104913. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  104914. <?php
  104915. declare (strict_types=1);
  104916. /*
  104917. * This file is part of sebastian/version.
  104918. *
  104919. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  104920. *
  104921. * For the full copyright and license information, please view the LICENSE
  104922. * file that was distributed with this source code.
  104923. */
  104924. namespace PHPUnitPHAR\SebastianBergmann;
  104925. use function end;
  104926. use function explode;
  104927. use function fclose;
  104928. use function is_dir;
  104929. use function is_resource;
  104930. use function proc_close;
  104931. use function proc_open;
  104932. use function stream_get_contents;
  104933. use function substr_count;
  104934. use function trim;
  104935. final class Version
  104936. {
  104937. private readonly string $version;
  104938. public function __construct(string $release, string $path)
  104939. {
  104940. $this->version = $this->generate($release, $path);
  104941. }
  104942. public function asString(): string
  104943. {
  104944. return $this->version;
  104945. }
  104946. private function generate(string $release, string $path): string
  104947. {
  104948. if (substr_count($release, '.') + 1 === 3) {
  104949. $version = $release;
  104950. } else {
  104951. $version = $release . '-dev';
  104952. }
  104953. $git = $this->getGitInformation($path);
  104954. if (!$git) {
  104955. return $version;
  104956. }
  104957. if (substr_count($release, '.') + 1 === 3) {
  104958. return $git;
  104959. }
  104960. $git = explode('-', $git);
  104961. return $release . '-' . end($git);
  104962. }
  104963. private function getGitInformation(string $path): bool|string
  104964. {
  104965. if (!is_dir($path . \DIRECTORY_SEPARATOR . '.git')) {
  104966. return \false;
  104967. }
  104968. $process = proc_open('git describe --tags', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $path);
  104969. if (!is_resource($process)) {
  104970. return \false;
  104971. }
  104972. $result = trim(stream_get_contents($pipes[1]));
  104973. fclose($pipes[1]);
  104974. fclose($pipes[2]);
  104975. $returnCode = proc_close($process);
  104976. if ($returnCode !== 0) {
  104977. return \false;
  104978. }
  104979. return $result;
  104980. }
  104981. }
  104982. <?php
  104983. declare (strict_types=1);
  104984. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  104985. class Exception extends \Exception
  104986. {
  104987. }
  104988. Tokenizer
  104989. Copyright (c) 2017 Arne Blankerts <arne@blankerts.de> and contributors
  104990. All rights reserved.
  104991. Redistribution and use in source and binary forms, with or without modification,
  104992. are permitted provided that the following conditions are met:
  104993. * Redistributions of source code must retain the above copyright notice,
  104994. this list of conditions and the following disclaimer.
  104995. * Redistributions in binary form must reproduce the above copyright notice,
  104996. this list of conditions and the following disclaimer in the documentation
  104997. and/or other materials provided with the distribution.
  104998. * Neither the name of Arne Blankerts nor the names of contributors
  104999. may be used to endorse or promote products derived from this software
  105000. without specific prior written permission.
  105001. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  105002. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
  105003. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  105004. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
  105005. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  105006. OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  105007. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  105008. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  105009. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  105010. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  105011. POSSIBILITY OF SUCH DAMAGE.
  105012. <?php
  105013. declare (strict_types=1);
  105014. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105015. class NamespaceUri
  105016. {
  105017. /** @var string */
  105018. private $value;
  105019. public function __construct(string $value)
  105020. {
  105021. $this->ensureValidUri($value);
  105022. $this->value = $value;
  105023. }
  105024. public function asString(): string
  105025. {
  105026. return $this->value;
  105027. }
  105028. private function ensureValidUri($value): void
  105029. {
  105030. if (\strpos($value, ':') === \false) {
  105031. throw new NamespaceUriException(\sprintf("Namespace URI '%s' must contain at least one colon", $value));
  105032. }
  105033. }
  105034. }
  105035. <?php
  105036. declare (strict_types=1);
  105037. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105038. class NamespaceUriException extends Exception
  105039. {
  105040. }
  105041. <?php
  105042. declare (strict_types=1);
  105043. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105044. class Token
  105045. {
  105046. /** @var int */
  105047. private $line;
  105048. /** @var string */
  105049. private $name;
  105050. /** @var string */
  105051. private $value;
  105052. /**
  105053. * Token constructor.
  105054. */
  105055. public function __construct(int $line, string $name, string $value)
  105056. {
  105057. $this->line = $line;
  105058. $this->name = $name;
  105059. $this->value = $value;
  105060. }
  105061. public function getLine(): int
  105062. {
  105063. return $this->line;
  105064. }
  105065. public function getName(): string
  105066. {
  105067. return $this->name;
  105068. }
  105069. public function getValue(): string
  105070. {
  105071. return $this->value;
  105072. }
  105073. }
  105074. <?php
  105075. declare (strict_types=1);
  105076. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105077. class TokenCollection implements \ArrayAccess, \Iterator, \Countable
  105078. {
  105079. /** @var Token[] */
  105080. private $tokens = [];
  105081. /** @var int */
  105082. private $pos;
  105083. public function addToken(Token $token): void
  105084. {
  105085. $this->tokens[] = $token;
  105086. }
  105087. public function current(): Token
  105088. {
  105089. return \current($this->tokens);
  105090. }
  105091. public function key(): int
  105092. {
  105093. return \key($this->tokens);
  105094. }
  105095. public function next(): void
  105096. {
  105097. \next($this->tokens);
  105098. $this->pos++;
  105099. }
  105100. public function valid(): bool
  105101. {
  105102. return $this->count() > $this->pos;
  105103. }
  105104. public function rewind(): void
  105105. {
  105106. \reset($this->tokens);
  105107. $this->pos = 0;
  105108. }
  105109. public function count(): int
  105110. {
  105111. return \count($this->tokens);
  105112. }
  105113. public function offsetExists($offset): bool
  105114. {
  105115. return isset($this->tokens[$offset]);
  105116. }
  105117. /**
  105118. * @throws TokenCollectionException
  105119. */
  105120. public function offsetGet($offset): Token
  105121. {
  105122. if (!$this->offsetExists($offset)) {
  105123. throw new TokenCollectionException(\sprintf('No Token at offest %s', $offset));
  105124. }
  105125. return $this->tokens[$offset];
  105126. }
  105127. /**
  105128. * @param Token $value
  105129. *
  105130. * @throws TokenCollectionException
  105131. */
  105132. public function offsetSet($offset, $value): void
  105133. {
  105134. if (!\is_int($offset)) {
  105135. $type = \gettype($offset);
  105136. throw new TokenCollectionException(\sprintf('Offset must be of type integer, %s given', $type === 'object' ? \get_class($value) : $type));
  105137. }
  105138. if (!$value instanceof Token) {
  105139. $type = \gettype($value);
  105140. throw new TokenCollectionException(\sprintf('Value must be of type %s, %s given', Token::class, $type === 'object' ? \get_class($value) : $type));
  105141. }
  105142. $this->tokens[$offset] = $value;
  105143. }
  105144. public function offsetUnset($offset): void
  105145. {
  105146. unset($this->tokens[$offset]);
  105147. }
  105148. }
  105149. <?php
  105150. declare (strict_types=1);
  105151. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105152. class TokenCollectionException extends Exception
  105153. {
  105154. }
  105155. <?php
  105156. declare (strict_types=1);
  105157. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105158. class Tokenizer
  105159. {
  105160. /**
  105161. * Token Map for "non-tokens"
  105162. *
  105163. * @var array
  105164. */
  105165. private $map = ['(' => 'T_OPEN_BRACKET', ')' => 'T_CLOSE_BRACKET', '[' => 'T_OPEN_SQUARE', ']' => 'T_CLOSE_SQUARE', '{' => 'T_OPEN_CURLY', '}' => 'T_CLOSE_CURLY', ';' => 'T_SEMICOLON', '.' => 'T_DOT', ',' => 'T_COMMA', '=' => 'T_EQUAL', '<' => 'T_LT', '>' => 'T_GT', '+' => 'T_PLUS', '-' => 'T_MINUS', '*' => 'T_MULT', '/' => 'T_DIV', '?' => 'T_QUESTION_MARK', '!' => 'T_EXCLAMATION_MARK', ':' => 'T_COLON', '"' => 'T_DOUBLE_QUOTES', '@' => 'T_AT', '&' => 'T_AMPERSAND', '%' => 'T_PERCENT', '|' => 'T_PIPE', '$' => 'T_DOLLAR', '^' => 'T_CARET', '~' => 'T_TILDE', '`' => 'T_BACKTICK'];
  105166. public function parse(string $source): TokenCollection
  105167. {
  105168. $result = new TokenCollection();
  105169. if ($source === '') {
  105170. return $result;
  105171. }
  105172. $tokens = \token_get_all($source);
  105173. $lastToken = new Token($tokens[0][2], 'Placeholder', '');
  105174. foreach ($tokens as $pos => $tok) {
  105175. if (\is_string($tok)) {
  105176. $token = new Token($lastToken->getLine(), $this->map[$tok], $tok);
  105177. $result->addToken($token);
  105178. $lastToken = $token;
  105179. continue;
  105180. }
  105181. $line = $tok[2];
  105182. $values = \preg_split('/\R+/Uu', $tok[1]);
  105183. if (!$values) {
  105184. $result->addToken(new Token($line, \token_name($tok[0]), '{binary data}'));
  105185. continue;
  105186. }
  105187. foreach ($values as $v) {
  105188. $token = new Token($line, \token_name($tok[0]), $v);
  105189. $lastToken = $token;
  105190. $line++;
  105191. if ($v === '') {
  105192. continue;
  105193. }
  105194. $result->addToken($token);
  105195. }
  105196. }
  105197. return $this->fillBlanks($result, $lastToken->getLine());
  105198. }
  105199. private function fillBlanks(TokenCollection $tokens, int $maxLine): TokenCollection
  105200. {
  105201. $prev = new Token(0, 'Placeholder', '');
  105202. $final = new TokenCollection();
  105203. foreach ($tokens as $token) {
  105204. $gap = $token->getLine() - $prev->getLine();
  105205. while ($gap > 1) {
  105206. $linebreak = new Token($prev->getLine() + 1, 'T_WHITESPACE', '');
  105207. $final->addToken($linebreak);
  105208. $prev = $linebreak;
  105209. $gap--;
  105210. }
  105211. $final->addToken($token);
  105212. $prev = $token;
  105213. }
  105214. $gap = $maxLine - $prev->getLine();
  105215. while ($gap > 0) {
  105216. $linebreak = new Token($prev->getLine() + 1, 'T_WHITESPACE', '');
  105217. $final->addToken($linebreak);
  105218. $prev = $linebreak;
  105219. $gap--;
  105220. }
  105221. return $final;
  105222. }
  105223. }
  105224. <?php
  105225. declare (strict_types=1);
  105226. namespace PHPUnitPHAR\TheSeer\Tokenizer;
  105227. use DOMDocument;
  105228. class XMLSerializer
  105229. {
  105230. /** @var \XMLWriter */
  105231. private $writer;
  105232. /** @var Token */
  105233. private $previousToken;
  105234. /** @var NamespaceUri */
  105235. private $xmlns;
  105236. /**
  105237. * XMLSerializer constructor.
  105238. *
  105239. * @param NamespaceUri $xmlns
  105240. */
  105241. public function __construct(?NamespaceUri $xmlns = null)
  105242. {
  105243. if ($xmlns === null) {
  105244. $xmlns = new NamespaceUri('https://github.com/theseer/tokenizer');
  105245. }
  105246. $this->xmlns = $xmlns;
  105247. }
  105248. public function toDom(TokenCollection $tokens): DOMDocument
  105249. {
  105250. $dom = new DOMDocument();
  105251. $dom->preserveWhiteSpace = \false;
  105252. $dom->loadXML($this->toXML($tokens));
  105253. return $dom;
  105254. }
  105255. public function toXML(TokenCollection $tokens): string
  105256. {
  105257. $this->writer = new \XMLWriter();
  105258. $this->writer->openMemory();
  105259. $this->writer->setIndent(\true);
  105260. $this->writer->startDocument();
  105261. $this->writer->startElement('source');
  105262. $this->writer->writeAttribute('xmlns', $this->xmlns->asString());
  105263. if (\count($tokens) > 0) {
  105264. $this->writer->startElement('line');
  105265. $this->writer->writeAttribute('no', '1');
  105266. $this->previousToken = $tokens[0];
  105267. foreach ($tokens as $token) {
  105268. $this->addToken($token);
  105269. }
  105270. }
  105271. $this->writer->endElement();
  105272. $this->writer->endElement();
  105273. $this->writer->endDocument();
  105274. return $this->writer->outputMemory();
  105275. }
  105276. private function addToken(Token $token): void
  105277. {
  105278. if ($this->previousToken->getLine() < $token->getLine()) {
  105279. $this->writer->endElement();
  105280. $this->writer->startElement('line');
  105281. $this->writer->writeAttribute('no', (string) $token->getLine());
  105282. $this->previousToken = $token;
  105283. }
  105284. if ($token->getValue() !== '') {
  105285. $this->writer->startElement('token');
  105286. $this->writer->writeAttribute('name', $token->getName());
  105287. $this->writer->writeRaw(\htmlspecialchars($token->getValue(), \ENT_NOQUOTES | \ENT_DISALLOWED | \ENT_XML1));
  105288. $this->writer->endElement();
  105289. }
  105290. }
  105291. }
  105292. ¸–æÐÜÍÄ·�Úªd®-÷šK›T´yÌ7órdó‰FïþY©f_ãµ÷ÇC­Y\bÿµ²˜ÛÑÖ´\���GBMB